ist das 'synonym' in einem 'typedef' obligatorisch?

8

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?

    
xtofl 14.01.2011, 12:09
quelle

6 Antworten

2

Ja, typedef benötigt ein anderes Argument. Das typedef wird nichts tun.

Trotzdem ist es kein Fehler, nur eine veraltete Verwendung von typedef .

Der Standard

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.

    
peoro 14.01.2011, 12:13
quelle
5

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.

    
Johannes Schaub - litb 14.01.2011 12:17
quelle
2
%Vor%     
Maxim Egorushkin 14.01.2011 12:11
quelle
2

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.

    
BЈовић 14.01.2011 12:15
quelle
1

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.)

    
quelle
1

Betrachten Sie die Parallelen zwischen:

%Vor%

GCC 4.2.1 mit keinen expliziten Warnungen aktiviert ( gcc -c xxx.c ) sagt von der ersten:

%Vor%

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:

%Vor%

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.

Zusammenfassung

  • Der überprüfte Code ist syntaktisch korrekt in C, sowohl C89 als auch C99.
  • Es ist auch, AFAIK, syntaktisch gültig in C ++ - aber es ist dort noch sinnloser als in C, da struct C { int i; }; ohne typedef den Typ C einführt (sowie struct C ).
  • Der überprüfte Code sollte nicht akzeptiert werden - es ist vernünftig zu fordern, dass er korrigiert wird.

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.

    
Jonathan Leffler 16.01.2011 01:26
quelle

Tags und Links