Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385325

Is this redundant "typedef" strictly legal?

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

Answers (1)

user743382
user743382

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 declared static (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

Related Questions