2009-12-11 17 views
5

Ho una struct:È possibile (legale) assegnare un'unione anonima in un letterale composto?

typedef struct _n 
{ 
    int type; 
    union { 
     char *s; 
     int i; 
    }; 
} n; 

Quando si tenta di assegnare un valore letterale composto, come:

node n1 = {1, 0}; 
node n2 = {2, "test"}; 

gcc mi dà alcuni avvisi quali:

warning: initialization makes pointer from integer without a cast 
warning: initialization from incompatible pointer type 

bene, è chiaro che il compilatore non è sicuro di me semplicemente assegnando un valore a un tipo possibilmente ambiguo. Tuttavia, anche se cerco di specificare più precisamente:

node n0 = {type: 1, i: 4}; 

ottengo:

error: unknown field ‘i’ specified in initializer 

Ho letto che se metto (union <union name>) prima i: allora può funzionare. Tuttavia, preferisco avere un'unione anonima. C'è un modo per farlo?

risposta

7

Le unioni anonime non sono C standard - sono un'estensione del compilatore. Consiglio vivamente di dare un nome al sindacato. Se ti ostini a usare un'unione anonima, allora si può solo dare un inizializzatore per il primo elemento di esso:

node n0 = {1, 0}; // initializes `s' to 0 

quando si compila con -Wall -Wextra -pedantic, gcc mi ha dato l'avvertimento "parentesi intorno initializer mancante", che è un avviso valido. L'inizializzazione dovrebbe in realtà essere specificata in questo modo:

node n0 = {1, {0}}; // initializes `s' to 0 

Ora questo dà solo un avviso che "ISO C non supporta senza nome struct/sindacati".

Se si dà il sindacato un nome, allora si può utilizzare una funzione chiamata C99 inizializzatori designati per inizializzare un membro specifico del sindacato:

typedef struct 
{ 
    int type; 
    union { 
     char *s; 
     int i; 
    } value; 
} node; 

node n0 = {1, { .s = "string"; }}; 
node n1 = {2, { .i = 123; }}; 

È necessario l'unione di avere un nome; altrimenti, il compilatore si lamenterà dell'inizializzatore designato al suo interno.

La sintassi che si sta tentando di utilizzare node n0 = {type: 1, i: 4} è una sintassi non valida; sembra che tu stavi cercando di utilizzare gli inizializzatori designati.

+0

Mi ha sorpreso la prima volta che l'ho visto, ma a GCC che è in realtà una sintassi di inizializzazione designata (sebbene deprecata). – ephemient

+0

la sintassi dell'inizializzatore (presumo deprecato) che ho ottenuto leggendo qualche codice del modulo del kernel .. Le strutture "fops" sono spesso scritte in questo modo. passerò al modo C99 ora. Peccato per le unioni anonime, non sapevo che non fossero standard, grazie per averlo chiarito. – Steve