2009-12-11 14 views
5

Ich habe eine Struktur:Ist es möglich (legal) eine anonyme Union in einem zusammengesetzten Literal zuzuweisen?

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

Wenn ich versuche, eine Verbindung wörtliche zuweisen, wie:

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

gcc gibt mir einige Warnungen wie:

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

Nun, es ist klar, dass der Compiler mir nicht sicher ist, nur einen Wert einem möglicherweise mehrdeutigen Typ zuzuweisen. Aber auch wenn ich versuche, genauer zu spezifizieren:

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

ich:

error: unknown field ‘i’ specified in initializer 

Ich habe gelesen, dass wenn ich (union <union name>) vor i: setzen, dann kann es funktionieren. Ich bevorzuge jedoch eine anonyme Vereinigung. Gibt es einen Weg, es zu tun?

Antwort

7

Anonyme Gewerkschaften sind nicht Standard C - sie sind eine Compiler-Erweiterung. Ich würde dringend empfehlen, der Gewerkschaft einen Namen zu geben. Wenn Sie sich mit einer anonymen bestehen, dann kann man nur einen Initialisierer für das erste Element davon geben:

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

Wenn mit -Wall -Wextra -pedantic zusammengestellt, gab gcc mir die Warnung „fehlenden Klammern um initializer“, die a gültige Warnung. Die initializer sollte eigentlich wie folgt angegeben werden:

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

Jetzt das gibt nur eine Warnung, dass „ISO C nicht unbenannte structs/Gewerkschaften unterstützt“.

Wenn Sie die Union einen Namen geben, dann können Sie eine C99-Funktion bezeichnet initializers genannt verwenden, um ein bestimmtes Mitglied der Vereinigung zu initialisieren:

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

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

Sie die Vereinigung müssen einen Namen haben; Andernfalls wird sich der Compiler über den designierten Initialisierer in ihm beschweren.

Die Syntax, die Sie verwenden wollten node n0 = {type: 1, i: 4} ist ungültige Syntax; Es sieht so aus, als ob Sie versucht haben, designierte Initialisierer zu verwenden.

+0

Es überraschte mich das erste Mal, als ich es sah, aber für GCC, das ist eigentlich legal (obwohl veraltet) bezeichnet Initialisierersyntax. – ephemient

+0

, dass (ich denke, veraltet) Initialisierung Syntax habe ich von einigen Kernel-Modul-Code lesen .. 'Fops' Strukturen werden oft auf diese Weise geschrieben. Ich werde jetzt auf den C99-Weg wechseln. Schade um die anonymen Gewerkschaften, ich wusste nicht, dass sie nicht Standard sind, danke, dass du das für mich geklärt hast. – Steve