Belloc
Belloc

Reputation: 6390

I believe [dcl.typedef]/1 has a defect, otherwise what am I missing?

[decl.pre]/10:

If the decl-specifier-seq contains the typedef specifier, the declaration is called a typedef declaration and each declarator-id is declared to be a typedef-name, synonymous with its associated type ([dcl.typedef]).

[Note 4: Such a declarator-id is an identifier ([class.conv.fct]). — end note]

If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with a declarator-id is a function type ([dcl.fct]) and an object declaration otherwise.

[dcl.typedef]/1:

Declarations containing the decl-specifier typedef declare identifiers that can be used later for naming fundamental or compound types. The typedef specifier shall not be combined in a decl-specifier-seq with any other kind of specifier except a defining-type-specifier, and it shall not be used in the decl-specifier-seq of a parameter-declaration ([dcl.fct]) nor in the decl-specifier-seq of a function-definition ([dcl.fct.def]). If a typedef specifier appears in a declaration without a declarator, the program is ill-formed.

The code below shows two typedef declarations:

typedef struct A{ int i; } structA;

and

typedef const int CI;

The first one is fine, as it satisfies the highlighted text in [dcl.typedef]/1, as shown below:

struct A { int; } is a class-specifier which is a defining-type-specifier.
structA is a typedef-name.

The second typedef declaration compiles as we all know, but it shouldn't, also according to the text highlighted above, as shown below:

const is a cv-qualifier, which is a type-specifier, which is a defining-type-specifier.
int is a simple-type-specifier, which is a type-specifier, which is a defining-type-specifier.

That is, we have two defining_type_specifiers in the same typedef declaration. I'm not a native English speaker, and I'm assuming that the article 'a' in the expression "except a defining-type-specifier" means that only one defining_type_specifier is accepted in a typedef declaration, according to the alluded paragraph.

Code:

typedef struct A{ int i; } structA;
typedef const int CI;

int main()
{
}

Upvotes: 1

Views: 77

Answers (1)

alex_noname
alex_noname

Reputation: 32163

There are exceptions to this rule described below that allows you to write such constructions:

typedef const signed short int si;

[dcl.type.general/2]

As a general rule, at most one defining-type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a defining-type-specifier-seq, and at most one type-specifier is allowed in a type-specifier-seq. The only exceptions to this rule are the following:

  • const can be combined with any type specifier except itself.
  • volatile can be combined with any type specifier except itself.
  • signed or unsigned can be combined with char, long, short, or int.
  • short or long can be combined with int.
  • long can be combined with double.
  • long can be combined with long.

Upvotes: 3

Related Questions