Un puntatore a un tipo incompleto può essere incompleto?


9

Può int (*)[]essere un tipo incompleto?

C 2018 6.2.5 1 dice:

In vari punti all'interno di un'unità di traduzione un tipo di oggetto può essere incompleto (privo di informazioni sufficienti per determinare la dimensione degli oggetti di quel tipo) o completo (con informazioni sufficienti).

Quindi sembra che se la dimensione di un tipo è nota, il tipo è completo. 6.2.6.1 28 specifica che determinati tipi di puntatori devono avere le stesse dimensioni (puntatori voide caratteri, puntatori a tipi compatibili, puntatori a strutture e puntatori a sindacati), ma i puntatori ad altri tipi possono variare.

In un'implementazione C in cui tutti i puntatori o tutti i puntatori a matrici inthanno le stesse dimensioni, allora la dimensione di int (*)[]è nota, quindi sarebbe completa. In un'implementazione che, ad esempio, utilizza diversi puntatori per array di grandi dimensioni, la dimensione non sarebbe nota, quindi è incompleta.

Come sottolinea MM , una struttura non deve contenere un membro di tipo incompleto, ad eccezione di un membro dell'array flessibile finale, per un vincolo del 6.7.2.1 3. Ciò suggerisce che un'implementazione con una dimensione di puntatori deve accettare struct { int (*p)[]; }mentre un'implementazione che ha differenti le dimensioni di tali array devono diagnosticare una violazione del vincolo. (Ciò a sua volta significa che una tale dichiarazione non fa parte della C. rigorosamente conforme)


6.2.5 (p22) aiuto? (o aggiunge più confusione che consente di completare il tipo incompleto con una dichiarazione successiva?)
David C. Rankin

@ DavidC.Rankin Nel 6.2.5 / 20 si dice persino che i puntatori sono sempre dei tipi completi
Christophe,

@LanguageLawyer: come sarebbe rilevante? La domanda è "Esiste una X che non è una Y?", Non "Esiste una X che è una Y?"
Eric Postpischil,

@LanguageLawyer: il fatto che void *sia completo mostra che un puntatore a un tipo incompleto può essere completo. Non mostra se un puntatore a un tipo incompleto può essere incompleto. Se uno si chiedesse "Può un mammifero essere un elefante?", Mostrando che "Un leone è un mammifero" non fornirebbe che un mammifero non può essere un elefante. La domanda si chiede se l'insieme X di puntatori di tipo incompleto possa contenere un elemento incompleto. Mostrare che l'insieme X di puntatori al tipo incompleto contiene un elemento completo è irrilevante.
Eric Postpischil,

@EricPostpischil Oops. Ho letto male il titolo come "Può un puntatore ad un tipo incompleto essere completo ?"
Avvocato delle lingue il

Risposte:


3

Una matrice di dimensioni sconosciute è incompleta:

Un tipo di array di dimensioni sconosciute è un tipo incompleto. Viene completato, per un identificatore di quel tipo, specificando la dimensione in una dichiarazione successiva (con collegamento interno o esterno).

Il tipo int (*)[]tuttavia non è incompleto: è un puntatore di una matrice di intdimensioni sconosciute.
E un puntatore ha una dimensione ben nota:

printf ("Size %d\n", sizeof(int (*)[]));

6.2.5 / 23: un tipo ha una dimensione costante nota se il tipo non è incompleto e non è un tipo di array a lunghezza variabile.

Inoltre puoi persino dereferenziarlo, grazie alla semantica dell'array:

typedef int (*T)[];
...
int a[10];
for (int i=0; i<10; i++) a[i]=i;
T p=a;
for (int i=0; i<10; i++) printf ("%d ",(*p)[i]);
printf ("\n");

modificare

Inoltre, un puntatore è sempre un tipo completo. È scritto nero su bianco in 6.2.5 / 20:

Un tipo di puntatore può essere derivato da un tipo di funzione o da un tipo di oggetto, chiamato tipo di riferimento. Un tipo di puntatore descrive un oggetto il cui valore fornisce un riferimento a un'entità del tipo di riferimento. Un tipo di puntatore derivato dal tipo di riferimento T viene talvolta chiamato '' puntatore a T ''. La costruzione di un tipo di puntatore da un tipo di riferimento viene chiamata '' derivazione del tipo di puntatore ''. Un tipo di puntatore è un tipo di oggetto completo.


Penso che tu l'abbia bollito e gcc è d'accordo. La struttura con puntatore all'array incompleto è simile alla domanda originale che avvia la discussione.
David C. Rankin

È rilevante solo l'ultimo paragrafo. L'esempio printfmostra solo che un puntatore a un array incompleto è completo nell'implementazione in cui è stato eseguito, come indicato nella domanda: se non fosse per 6.2.5 20, citato nell'ultimo paragrafo, potrebbe non riuscire a compilare. 6.2.5 23 non è rilevante; ci dice che la dimensione è nota e costante se è completa e sappiamo già che essere completi significa che la dimensione è nota.
Eric Postpischil,

6.2.5 20 è interessante. Ho ipotizzato che non si intendesse avere questa conseguenza, ma significa che tutti i puntatori a tipi completi che hanno lo stesso tipo quando incompleti devono avere le stesse dimensioni. Ad esempio, tutti i puntatori a matrici di intdevono avere le stesse dimensioni l'uno dell'altro e tutti i puntatori a matrici di un determinato structdevono avere le stesse dimensioni dell'altro, sebbene forse non tutti i puntatori a matrici di tipi diversi di structdevono avere le stesse dimensioni come a vicenda.
Eric Postpischil,

1
@EricPostpischil forse il testo "Allo stesso modo, i puntatori a versioni qualificate o non qualificate di tipi compatibili devono avere gli stessi requisiti di rappresentazione e allineamento." dovrebbe essere interpretato per dire che T(*)[]deve avere le stesse dimensioni di T(*)[5], poiché sono tipi compatibili e potremmo aggiungere o rimuovere qualificatori
MM

Consentire a tipi compatibili di dimensioni diverse porterebbe a un sacco di problemi, probabilmente è un difetto che lo standard non lo escluda esplicitamente
MM
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.