Reputation: 385325
I found the following declaration in v0.9.2 of the ACE Radius library:
// Types of attribute data
typedef enum AttributeFormat_e
{
E_ATTR_FORMAT_INTEGER,
E_ATTR_FORMAT_IP_ADDRESS,
E_ATTR_FORMAT_STRING,
E_ATTR_FORMAT_VENDOR_SPECIFIC,
E_ATTR_FORMAT_USER_PASSWORD,
E_ATTR_FORMAT_CHAP_PASSWORD
};
That leading typedef
is completely meaningless and should not be present.
Indeed, GCC emits the following diagnostic:
/usr/include/ace-radius/RadiusAttribute.h:597: warning: ‘typedef’ was ignored in this declaration
Now, this is ultimately harmless, despite being a bizarre sort of half-meaningful half-C declaration in a file that otherwise may only be parsed as C++ (the declaration is found as a private
member in a class
).
But purely out of curiosity I wanted to know whether this is strictly compliant, or strictly ill-formed, and couldn't quite tell from the standard.
Is this leading typedef
legal? Or is GCC being permissive?
Upvotes: 1
Views: 757
Reputation:
It's legal, for the simple reason that there's no rule against it anywhere in the standard. The effect of typedef
is only defined as what effect it has on names defined with the typedef
specifier, so when there are no names defined with that specifier, the behaviour is well-defined: typedef
simply has no effect.
The grammar in general does not require any declarators for a simple-declaration, and you probably already know this, since you would not have been surprised to see enum AttributeFormat_e { ... };
without the typedef
. The productions are
simple-declaration:
decl-specifier-seqopt init-declarator-listopt;
attribute-specifier-seq decl-specifier-seqopt init-declarator-list;
As long as no attribute-specifier-seq is present in a simple-declaration, the init-declarator-list is optional.
typedef int;
would be invalid, as would int;
without the typedef
, but that's a different rule: the rule there is that a declaration has to declare something. That rule doesn't apply to what's in your question, because that declaration does declare something. More precisely, C++11 [dcl.dcl]p3:
In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (Clause 9) or enumeration (7.2), that is, when the decl-specifier-seq contains either a class-specifier, an elaborated-type-specifier with a class-key (9.1), or an enum-specifier. [...]
The code in the question is declaring an enumeration, so this rule is not violated.
static enum E { x };
would be invalid, but that's another different rule: C++11 [dcl.stc]p1:
[...] If a storage-class-specifier appears in a decl-specifier-seq, there can be no
typedef
specifier in the same decl-specifier-seq and the init-declarator-list of the declaration shall not be empty (except for an anonymous union declared in a named namespace or in the global namespace, which shall be declaredstatic
(9.5)). [...]
const enum E { x };
would also be invalid, but that's a third different rule: C++11 [dcl.type.cv]p1:
[...] If a cv-qualifier appears in a decl-specifier-seq, the init-declarator-list of the declaration shall not be empty. [...]
There is simply no such rule anywhere for typedef
.
Upvotes: 9