I was quite surprised when I saw the following code compile without errors or warnings in g++-4.2:
typedef enum test { one };
My assumption was that if you used the typedef keyword it would require an extra identifier as in:
typedef enum test { one } test;
As already mentioned, g++-4.2 accepts it without even a warning. Clang++ 3.0 warns “warning: typedef requires a name“, similarly Comeau warns “warning: declaration requires a typedef name“, and g++-4.6 informs: “warning: ‘typedef’ was ignored in this declaration“.
I have not been able to identify where in the standard this is allowed, and I find it slightly confusing that two of the compilers warn that it is required, shouldn’t it be an error if the typedef-name is required but not present?
UPDATE: I have checked in C with the same compilers. Clang and comeau yield the same output, gcc gives a warning: “warning: useless storage class specifier in empty declaration“, which seems even more confusing.
UPDATE: I have checked removing the name of the enum and the results are the same:
typedef enum { one };
Similarly with a named struct:
typedef struct named { int x };
But not with an unnamed struct, in which case the code was rejected in g++ (4.2/4.6) with “error: missing type-name in typedef-declaration“, gcc (4.2/4.6) gave a warning: “warning: unnamed struct/union that defines no instances“, clang++ “warning: declaration does not declare anything“, comeau “error: declaration requires a typedef name“
It is a degenerate syntax that is allowed but provides no benefit. Most modern compilers can be provoked into emitting a warning about it; by default, they may not. Without the typedef name, the keyword
typedefis superfluous; in your example, it is completely equivalent to:Another place where it can occur is with a structure:
This is equivalent to:
Note that
typedefis officially (or syntactically) a ‘storage class specifier’, likestatic,extern,autoandregister.C Standard
In ISO/IEC 9899:1999 (that’s the C standard), we find:
And (as requested):
If you track through that syntax, there are a lot of degenerate possibilities, and what you showed is just one of the many.
C++ Standard
It is possible that C++ has different rules.
In ISO/IEC 14882:1998 (the original C++ standard), we find in §7.1.1 ‘Storage class specifiers’ that C++ does not treat
typedefas a storage class; the list addsmutableand excludestypedef. So, the grammatical specification oftypedefin C++ is definitely different from the C specification.Declarations specify how names are to be interpreted. Declarations have the form
Since §7 ¶5 says that
typedefnames come from the init-declarator and the init-declarator-list is tagged ‘opt‘, I think that means that thetypedefname can be omitted in C++, just as in C.