Code, der anonyme Strukturen in einer for-Schleife deklarierte, funktionierte in gcc mit -std = c99 / gnu99
%Vor%Wenn ich jedoch zu clang wechsel, erhalte ich den Fehler:
%Vor%Warum ist das ein Fehler? Warum würde es einige Typen zulassen (z. B. "int"), aber keine anderen (z. B. struct {int foo;})? Dies scheint inkonsistent zu sein. Kann clang nicht richtig implementiert werden oder ist der Code ungültig c99 und gcc unterstützt ihn einfach?
Kennt jemand eine Möglichkeit, mehr als einen Variablentyp in einer for-Schleife zu deklarieren, die von clang unterstützt wird? (Dies ist nützlich für Makros.)
BEARBEITEN:
Da Leute gefragt haben, warum das nützlich ist, füge ich einen Beispielcode ein:
%Vor%Dies ist ein wirklich praktisches Makro, das ich geschrieben habe, das über einen AVL-Baum in der Tiefe iteriert - erste Reihenfolge auf dem Stapel. Seit dem Deklarieren anonymer Strukturen in der for-Schleife ist nicht erlaubt, obwohl ich das Makro weniger intuitiv zu verwenden machen muss. Ich konnte die Deklaration für den Rest des Baumes nicht out-source, da es ein Array variabler Länge verwendet.
Ich bin von den vorherigen Antworten nicht überzeugt. Es baut erfolgreich mit gcc (mit -Wall -pedantic
), nur nicht mit clang oder Visual Studio.
Microsoft hat als Fehler ein extrem ähnliches Problem mit Visual Studio in diesem Microsoft Connect Fehler Item .
6.8.5 besagt, dass Deklarationen von Bezeichnern innerhalb des for-init-Ausdrucks nicht typedef
, extern
oder static
sein dürfen (die einzigen anderen Speicherklassenbezeichner als auto
und register
).
Der Speicherklassenbezeichner auto
in C99 ist standardmäßig und implizit. Der Strukturtyp und der Bezeichner i
sind dann automatisch (Umfang innerhalb dieses Codeblocks). Sicher ist der Code dann gültig? Ich sehe nicht, wie 6.8.5 die Deklaration eines Typs verbietet.
Ich schlage vor, dass gcc korrekt ist, und es ist ein Fehler bei der Implementierung von clang und Visual Studio.
C 1999 6.8.5 3: "Der Deklarationsteil einer for-Anweisung darf nur Bezeichner für Objekte mit der Speicherklasse auto oder register deklarieren." Ihr Code deklariert das Objekt i, deklariert aber auch die Struktur. Wenn Sie die Struktur früher deklarieren (mit einem Tag oder in einem typedef), können Sie sie in der for
-Anweisung verwenden.
In C99 ist das nicht erlaubt. §6.8.5 sagt:
3 Der Deklarationsteil einer for-Erklärung darf nur deklarieren Bezeichner für Objekte mit der Speicherklasse
auto
oderregister
.
Die von Ihnen angezeigte Deklaration deklariert zusätzlich zum Objekt i
einen Typ, und ein Typ ist kein Bezeichner für ein Objekt.
Als Workaround können Sie für jedes Strukturelement, das genau einmal Schleifen ausführt, eine äußere for-Schleife hinzufügen. Es ist hässlich, aber zumindest aus Sicht der Nutzung wird es das gleiche sein