Ich habe das in einem Code-Review gesehen:
%Vor%Es kompiliert.
Abgesehen davon, dass es C-style ist, wo Strukturen in einem separaten 'namespace' sind und typedeffed sein müssen, um später zu verwenden, fand ich es seltsam, dass mit diesem typedef nichts definiert ist ...
Also: benötigt typedef
kein type-Argument und kein Alias-Argument?
Ja, typedef
benötigt ein anderes Argument. Das typedef
wird nichts tun.
Trotzdem ist es kein Fehler, nur eine veraltete Verwendung von typedef
.
C (n1256 in 6.7.7) spricht von typedef
. Es heißt nicht, dass diese Verwendung veraltet ist, aber Compiler melden dies, da eine solche Anweisung keine Auswirkungen hat.
Ein kurzer Blick auf n3225 zeigt keine Anforderung, dass ein Name vorhanden sein muss. Der Text, der am nächsten kommt, sagt nur
In einer einfachen Deklaration kann die optionale init-declator-list nur weggelassen werden, wenn eine Klasse (Klausel 9) oder eine Enumeration (7.2) deklariert wird, dh wenn decl-specifier-seq entweder einen Klassenspezifizierer enthält ein elaborierter Typ-Spezifizierer mit einem Klassenschlüssel (9.1) oder ein Enumerationsspezifizierer.
Ihr Code scheint also gültig zu sein, aber ich denke, er riecht schlecht.
Sie verwenden sehr wahrscheinlich einen sehr alten Compiler, mit dem Sie diese Zeile kompilieren können. Verwenden Sie g ++ 4.3.0 (das schon ziemlich alt ist), ohne zusätzliche Optionen, geben Sie folgendes ein:
%Vor%Versuchen Sie also, das mit einem Compiler zu kompilieren, der c ++ -Standard-konform ist.
Tatsächlich ist das nicht gültig. Sie verwenden das Schlüsselwort typedef
, um einen Alias zu erstellen, und geben dann nicht an, wie der Alias sein soll!
(Streng genommen ist es veraltet, nicht ungültig. Aber hey.)
Betrachten Sie die Parallelen zwischen:
%Vor% GCC 4.2.1 mit keinen expliziten Warnungen aktiviert ( gcc -c xxx.c
) sagt von der ersten:
Beachten Sie, dass dies nur Warnungen sind. Sie sind kein Fehler, weil der Standard die Notation erlaubt, obwohl dies nicht sehr viel bringt. In jedem Fall deklariert das Beispiel einfach einen Strukturtyp, der unter dem Namen struct C
oder struct P
verwendet werden kann. Die Speicherklassen sind irrelevant, weil kein Objekt benannt ist. In C ++ deklarieren diese Deklarationen auch die Typen C
und P
(dies gilt jedoch auch, wenn typedef
oder extern was not there); in C, those types (
C and
P ') nicht deklariert sind.
Im C-Standard wird typedef
als Speicherklasse behandelt, wie extern
und static
sind Speicherklassen. Das bedeutet, dass der folgende Code legitim ist:
Er deklariert die gleichen zwei Strukturtypen wie zuvor, aber jetzt deklariert typedef
einen Alias für struct C
, der name1
ist, und die Zeile extern
gibt an, dass eine andere Übersetzungseinheit (TU) eine Variable namens definiert name2
vom Typ struct P
. Weder ist leer (außer dass die Definitionen später in der 2-zeiligen TU nicht verwendet werden).
Der C-Standard erlaubt viele seltsame Dinge. Zum Beispiel:
%Vor%Es ist eine vollkommen gültige - aber völlig abnormale - Art zu schreiben:
%Vor%Es gibt einen Abschnitt in C99 §6.11.5 (unter Future Language Directions), der besagt:
6.11.5 Speicherklassenspezifizierer
Die Platzierung eines Speicherklassenspezifizierers, der nicht am Anfang der Deklaration liegt Spezifizierer in einer Deklaration ist eine veraltete Funktion.
Das macht mein seltsames Beispiel gegen §6.11.5.
struct C { int i; };
ohne typedef den Typ C einführt (sowie struct C
). Der richtige Fix könnte sein, die Speicherklasse ( typedef
) zu entfernen, oder es könnte ein Name als Alias für struct C
eingeführt werden. Da der Code ohne den Alias kompiliert wird, ist es wahrscheinlicher, dass die Speicherklasse entfernt wird.