Come parte di rispondere a un'altra domanda, mi sono imbattuto in un pezzo di codice come questo, che gcc compila senza lamentarsi.Come è legale fare riferimento a un tipo non definito all'interno di una struttura?
typedef struct {
struct xyz *z;
} xyz;
int main (void) {
return 0;
}
Questo è il mezzo che ho sempre usato per costruire i tipi che puntano a se stessi (per esempio, le liste collegate), ma ho sempre pensato che dovevi nome struct così si potrebbe usare autoreferenzialità . In altre parole, non è possibile utilizzare xyz *z
all'interno della struttura perché il typedef non è ancora completo in quel punto.
Ma questo particolare esempio fa non nome della struttura e si compila ancora. Inizialmente pensavo che nel compilatore ci fosse della magia nera che traduceva automaticamente il codice precedente perché la struttura e i nomi typedef erano gli stessi.
Ma questa piccola bellezza funziona così:
typedef struct {
struct NOTHING_LIKE_xyz *z;
} xyz;
Che cosa mi manca qui? Questa sembra una chiara violazione poiché non esiste un tipo struct NOTHING_LIKE_xyz
definito ovunque.
Quando cambio da un puntatore ad un tipo effettivo, ottengo l'errore previsto:
typedef struct {
struct NOTHING_LIKE_xyz z;
} xyz;
qqq.c:2: error: field `z' has incomplete type
Inoltre, quando rimuovo il struct
, ottengo un errore (parse error before "NOTHING ...
).
È consentito in ISO C?
Update: Un struct NOSUCHTYPE *variable;
compila anche quindi non è solo all'interno strutture dove sembra essere valido. Non riesco a trovare nulla nello standard c99 che permetta questa clemenza per i puntatori di struttura.
Il secondo e il terzo blocco di codice sono identici. – badp
Spiacente, risolto quello. Errore utente cut'n'paste. – paxdiablo
+1, questa domanda ha lasciato parecchie persone grattarsi la testa (me inclusa). –