$ cc us.c
$ cc -std=c99 us.c
us.c:18:4: warning: declaration does not declare anything
us.c: In function ‘main’:
us.c:26:4: error: ‘struct node’ has no member named ‘int_n’
Verwenden GCC ohne -std Option kompiliert den obigen Code ohne Probleme (und der ähnliche Code funktioniert ziemlich gut), aber es scheint so c99 lässt diese Technik nicht zu. Warum ist das so und ist es möglich, es zu machen? c99 (oder c89, c90) kompatibel? Vielen Dank.
Nur eine Anmerkung, clang kompiliert gegebenen Code mit und ohne -std=c99 lautlos, ohne Fehler und Warnungen.
– Martin
12. Juli 2010 um 11:58 Uhr
R.. GitHub HÖREN SIE AUF, ICE ZU HELFEN
Anonyme Unions sind eine GNU-Erweiterung, nicht Teil einer Standardversion der C-Sprache. Sie können -std=gnu99 oder ähnliches für c99+GNU-Erweiterungen verwenden, aber es ist am besten, richtiges C zu schreiben und sich nicht auf Erweiterungen zu verlassen, die nichts als syntaktischen Zucker liefern …
Bearbeiten: Anonyme Gewerkschaften wurden in C11 hinzugefügt, sodass sie jetzt ein Standardbestandteil der Sprache sind. Vermutlich GCCs -std=c11 lässt Sie sie verwenden.
Update 2019, keine Verwendung erforderlich -std=c11 mit aktuellen stabilen Versionen für anonym struct oder union. Ich bin mir nicht sicher, welche Version vor GCC 8.2 als Standard übernommen wurde.
– Undefiniertes Verhalten
26. Februar 2019 um 13:21 Uhr
@UndefinedBehavior GCC 5 wird bereits erweitert __STDC_VERSION__ wie 201112L, während GCC 4.8 es überhaupt nicht erweitert – beide mit Standardeinstellungen. Anscheinend ist es also GCC 5, das standardmäßig auf C11 (eigentlich gnu11) eingestellt ist.
– Ruslan
26. August 2020 um 14:06 Uhr
schwarz
Ich finde diese Frage etwa anderthalb Jahre nach allen anderen, daher kann ich eine andere Antwort geben: Anonyme Strukturen sind nicht im C99-Standard, aber im C11-Standard. GCC und Clang unterstützen dies bereits (der C11-Standard scheint die Funktion von Microsoft aufgehoben zu haben, und GCC bietet seit einiger Zeit Unterstützung für einige MSFT-Erweiterungen).
Die Ironie besteht darin, dass die Semantik anonymer Strukturen und Vereinigungen in Dennis Ritchies C-Compiler von 1974 verfügbar war, und ich glaube, gcc hatte anonyme Strukturen und Vereinigungen in den Tagen vor dem C89-Standard unterstützt. Einige Leute scheinen zu denken, dass es sich um ein neues Feature handelt, aber es stellt lediglich eine wiedergewonnene Fähigkeit dar, die niemals hätte verloren gehen dürfen.
– Superkatze
26. Mai 2018 um 17:55 Uhr
Nun, die Lösung bestand darin, die Instanz der Union zu benennen (die als Datentyp anonym bleiben kann) und diesen Namen dann als Proxy zu verwenden.
Hinweis: Ich bin mit dieser Lösung sowieso nicht glücklich.
Du solltest glücklich sein! Dies ist die Standardmethode für den Zugriff auf Gewerkschaftsmitglieder, die seit dem 1. Januar 1970 garantiert mit jedem C-Compiler funktioniert.
– Jens
23. August 2012 um 7:11 Uhr
Es verfälscht den Code etwas, keine Ahnung, warum es nicht in K&R C enthalten war, scheint mir ein einfaches und nützliches Feature zu sein … Wie auch immer, ich verwende die gleiche Proxy-Methode, aber definiere Makros, um das ganze Tippen zu vermeiden.
– Arran Cudbard-Bell
3. Dezember 2014 um 3:16 Uhr
Mir ist klar, dass dies ein sehr alter Beitrag ist, aber das Kopieren des tatsächlichen Codes anstelle eines Diff-Patches ist viel besser lesbar.
– jap
25. April 2016 um 1:10 Uhr
@ysap aber wie hast du dann den unterschied erkannt?
– binki
20. August 2016 um 1:21 Uhr
@binki vielleicht brauchen wir einen DiffOverflow, wo Leute Codeschnipsel posten und Antworten aus Diffs bestehen, die sie verbessern (möglicherweise aufeinander basierend) 🙂
– Thomas
22. August 2016 um 10:40 Uhr
Undefiniertes Verhalten
Nur zur Klärung von anonym struct oder anonym union.
Ein namenloses Mitglied dessen Typbezeichner ein Strukturbezeichner mit ist keine Markierung heißt ein anonyme Struktur; ein namenloses Mitglied dessen Typbezeichner ein Union-Bezeichner mit ist keine Markierung heißt ein anonyme Vereinigung. Die Mitglieder einer anonymen Struktur oder Vereinigung werden als Mitglieder der enthaltenden Struktur oder Vereinigung betrachtet. Dies gilt rekursiv, wenn die enthaltende Struktur oder Union ebenfalls anonym ist.
Kennung: optional, Ihr benutzerdefinierter Name für die struct oder union;
Deklarationsliste: Mitglieder, Ihre Variablen, anonym struct und anonym union
Stichworte: Optional. Wenn Sie eine haben typedef vor dem Typbezeichnerdas Stichworte Alias sind und nicht Stichworte.
Es ist eine anonyme struct oder anonym union nur wenn es keinen Bezeichner und kein Tag hat und in einem anderen existiert struct oder union.
struct s {
struct { int x; }; // Anonymous struct, no identifier and no tag
struct a { int x; }; // NOT Anonymous struct, has an identifier 'a'
struct { int x; } b; // NOT Anonymous struct, has a tag 'b'
struct c { int x; } C; // NOT Anonymous struct
};
struct s {
union { int x; }; // Anonymous union, no identifier and no tag
union a { int x; }; // NOT Anonymous union, has an identifier 'a'
union { int x; } b; // NOT Anonymous union, has a tag 'b'
union c { int x; } C; // NOT Anonymous union
};
typedef hell: wenn du eine hast typedef Der Tag-Teil ist kein Tag mehr, sondern ein Alias für diesen Typ.
struct a { int x; } A; // 'A' is a tag
union a { int x; } A; // 'A' is a tag
// But if you use this way
typedef struct b { int x; } B; // 'B' is NOT a tag. It is an alias to struct 'b'
typedef union b { int x; } B; // 'B' is NOT a tag. It is an alias to union 'b'
// Usage
A.x = 10; // A tag you can use without having to declare a new variable
B.x = 10; // Does not work
B bb; // Because 'B' is an alias, you have to declare a new variable
bb.x = 10;
Das Beispiel unten ändert sich einfach struct zum unionfunktioniert genauso.
struct a { int x; }; // Regular complete struct type
typedef struct a aa; // Alias 'aa' for the struct 'a'
struct { int x; } b; // Tag 'b'
typedef struct b bb; // Compile, but unusable.
struct c { int x; } C; // identifier or struct name 'c' and tag 'C'
typedef struct { int x; } d; // Alias 'd'
typedef struct e { int x; } ee; // struct 'e' and alias 'ee'
Svisstack
Union muss einen Namen haben und wie folgt deklariert werden:
Nicht in C11, aber in C99 ja. Aber da wir die Drei-Jahres-Marke seit seiner Veröffentlichung überschritten haben, ist es vielleicht an der Zeit, -std=c11 zu übergeben :).
– Arran Cudbard-Bell
3. Dezember 2014 um 3:14 Uhr
Ihr Codebeispiel ist in C++, nicht in C. union UPair erklärt nicht a UPair Typ in C. Die Namespaces für Tags und Typen sind in C getrennt, aber nicht in C++.
– Patrick Schlüter
14. September 2018 um 10:54 Uhr
der JPster
Eine andere Lösung besteht darin, den gemeinsamen Header-Wert (enum node_type type) in jede Struktur und machen Sie Ihre Struktur der obersten Ebene zu einer Union. Es ist nicht gerade “Don’t Repeat Yourself”, aber es vermeidet sowohl anonyme Vereinigungen als auch unbequem aussehende Proxy-Werte.
Nicht in C11, aber in C99 ja. Aber da wir die Drei-Jahres-Marke seit seiner Veröffentlichung überschritten haben, ist es vielleicht an der Zeit, -std=c11 zu übergeben :).
– Arran Cudbard-Bell
3. Dezember 2014 um 3:14 Uhr
Ihr Codebeispiel ist in C++, nicht in C. union UPair erklärt nicht a UPair Typ in C. Die Namespaces für Tags und Typen sind in C getrennt, aber nicht in C++.
– Patrick Schlüter
14. September 2018 um 10:54 Uhr
Cellkon
Wenn ich mir 6.2.7.1 von C99 anschaue, sehe ich, dass die Kennung optional ist:
Ich habe auf und ab gesucht und kann keinen Hinweis darauf finden, dass anonyme Gewerkschaften gegen die Spezifikation verstoßen. Das ganze Suffix -opt zeigt in diesem Fall an, dass das Ding identifier ist gemäß 6.1 optional.
Ich glaube hier liegt ein Missverständnis vor. Der Bezeichner für eine Struktur oder Union Schild ist optional, aber nicht der Bezeichner, der deklariert wird. Das können Sie nicht sagen union { ... }; innerhalb eines Aggregats aus demselben Grund, aus dem Sie es nicht sagen können int;. Im Union-Fall erlauben Compiler-Erweiterungen dies, da Sie Bezeichner in der verwenden können {...} Teil bei Verwendung einer anonymen Union.
– Jens
22. August 2012 um 8:39 Uhr
14109400cookie-checkAnonyme Vereinigung innerhalb der Struktur nicht in c99?yes
Nur eine Anmerkung, clang kompiliert gegebenen Code mit und ohne
-std=c99
lautlos, ohne Fehler und Warnungen.– Martin
12. Juli 2010 um 11:58 Uhr