The validity of `typedef struct foo {int bar};`

This question arises from the question Is a structure {...}; type or unnamed variable?

In this question, OP asked about

typedef struct student_s { char* name; int age; double height; struct student_s* next; }; 

I ask about the legality of the above. Is diagnostics required if the code containing above is compiled (or to simplify it, typedef struct foo {int bar;}; )?

I believe it is legal that diagnosis is not required from the point of view of a language attorney. (In addition: I am not a proponent of using this. He is very worthy of diagnosis. I would very much like the compiler to warn me if I mistakenly wrote the code as indicated above.)


Section 6.7 of the C11 standard dictates the syntax of declarations: declare-specificers init-declarator-list opt ; Please note that the init-declarator list is optional. This may make typedef int; valid. This is not because the standard also states that

A declaration other than a static_assert declaration must declare at least a declarator (except for function parameters or members of a structure or union), a tag, or enumeration members.

Thus, typedef int; and typedef struct {int bar}; are illegal because they do not declare a declarator, tag, or listing member.

On the other hand, it seems to me that typedef struct foo {int bar;}; is legal because he announces something. In particular, it declares and defines a struct foo tag.

Is the above reasoning correct?

+6
source share
3 answers

6.7.1 Storage class specifiers define typedef as a storage class specifier with the following comment: a typedef specifier is called a storage class specifier for syntactic convenience only;

And 6.7 the declaration contains:

Syntax:

  • Ad:
    • Init-declarator-list opt
  • declaration specifiers:
    • Opt storage class specifier
    • Opt qualifier type specifier declaration
    • opt qualifiers
    • opt specifier specifier specifier
  • INIT-descriptor-list:
    • INIT descriptor
    • init-declarator-list, init-declarator
  • INIT descriptor:
    • descriptor
    • declarator = initializer

The first limitation: at least the declarator declares the declaration (except for the parameters of the function or members of the structure or association), the tag or members of the enumeration

Since the initialization declaration list is optional in the declaration, if a declarator or tag is declared, I would say that typedef struct foo {int bar;}; is a declaration decomposed as storage-class-specifier type-specifier without init-declarator. But since the type specifier declares an internally tag ( foo ), the restriction is respected.

My conclusion is that such a construction is valid and only displays a warning to the compilers.

+1
source

The cited quote says that the declaration declares, among other things, a tag.

So this ad

 typedef struct student_s { char* name; int age; double height; struct student_s* next; }; 

just declares struct student_s and is equivalent to declaring without typedef specifier

 struct student_s { char* name; int age; double height; struct student_s* next; }; 

No typedef name is entered in the scope.

+2
source

this typedef:

 typedef struct student_s { char* name; int age; double height; struct student_s* next; }; 

gives the following:

 warning useless storage class specifier in empty declaration [enabled by default] 

Thus, the syntax is valid, but without declaration, the code is garbage

0
source

All Articles