Is the typedef-name optional in a typedef declaration?

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 typedef is superfluous; in your example, it is completely equivalent to:

enum test { one };

Another place where it can occur is with a structure:

typedef struct SomeThing { int whatever; };

This is equivalent to:

struct SomeThing { int whatever; };

Note that typedef is officially (or syntactically) a ‘storage class specifier’, like static, extern, auto and register.


C Standard

In ISO/IEC 9899:1999 (that’s the C standard), we find:

§6.7 Declarations

Syntax

declaration:

declaration-specifiers init-declarator-listopt;

declaration-specifiers:

storage-class-specifier declaration-specifiersopt

type-specifier declaration-specifiersopt

type-qualifier declaration-specifiersopt

function-specifier declaration-specifiersopt

init-declarator-list:

init-declarator

init-declarator-list , init-declarator

init-declarator:

declarator

declarator = initializer

And (as requested):

§6.7.1 Storage-class specifiers

Syntax

storage-class-specifier:

typedef

extern

static

auto

register

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 typedef as a storage class; the list adds mutable and excludes typedef. So, the grammatical specification of typedef in C++ is definitely different from the C specification.

§7 Declarations

Declarations specify how names are to be interpreted. Declarations have the form

declaration-seq:

declaration

declaration-seq declaration

declaration:

block-declaration

function-definition

template-declaration

explicit-instantiation

explicit-specialization

linkage-specification

namespace-definition

block-declaration:

simple-declaration

asm-definition

namespace-alias-definition

using-declaration

using-directive

simple-declaration:

decl-specifier-seqopt init-declarator-listopt ;

¶5 If the decl-specifier-seq
contains the typedef specifier, the declaration is called a typedef declaration and
the name of each init-declarator
is declared to be a typedef-name,
synonymous with its associated type
(7.1.3).

§7.1 Specifiers [dcl.spec]

The specifiers that can be used in a declaration are

decl-specifier:

storage-class-specifier

type-specifier

function-specifier

friend

typedef

decl-specifier-seq:

decl-specifier-seqopt

decl-specifier

§7.1.1 Storage class specifiers [dcl.stc]

storage-class-specifier:

auto

register

static

extern

mutable

§7.1.2 Function specifiers [dcl.fct.spec]

function-specifier:

inline

virtual

explicit

§7.1.3 The typedef specifier [dcl.typedef]

Declarations containing the decl-specifier
typedef declare identifiers that can be used later for naming
fundamental (3.9.1) or compound (3.9.2) types. The typedef specifier shall not be used in a function-definition
(8.4), and it shall not be combined in a decl-specifier-seq
with any other kind of specifier except
a type-specifier.

typedef-name:

identifier

In a given scope, a typedef specifier can be used to redefine the name of any type declared in that scope
to refer to the type to which it already refers. [Example:

typedef struct s { /* ... */ } s;
typedef int I;
typedef int I;
typedef I I;

—end example]

§7.1.4 The friend specifier [dcl.friend]

The friend specifier is used to specify access to class members; see 11.4.

§7.1.5 Type specifiers [dcl.type]

type-specifier:

simple-type-specifier

class-specifier

enum-specifier

elaborated-type-specifier

cv-qualifier


Since §7 ¶5 says that typedef names come from the init-declarator and the init-declarator-list is tagged ‘opt‘, I think that means that the typedef name can be omitted in C++, just as in C.

Leave a Comment