6

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

In that question, the OP asked about

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

I am asking about the legality of the above. Is a diagnostic required when code containing the above is compiled (or to make it simpler, typedef struct foo {int bar;};)?

My take is that it is legal, that a diagnostic is not required from a language lawyer perspective. (Aside: I am not advocating using this. It is very worthy of a diagnostic. I would very much want the compiler to warn me if I mistakenly wrote code like the above.)


Section 6.7 of the C11 standard dictates the syntax of a declaration: declaration-specifiers init-declarator-listopt ; Note that the init-declarator-list is optional. This might lead one to think that typedef int; is valid. It isn't because the standard also says that

A declaration other than a static_assert declaration shall declare at least a declarator (other than the parameters of a function or the members of a structure or union), a tag, or the members of an enumeration.

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

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

Is the above reasoning correct?

Community
  • 1
  • 1
David Hammen
  • 32,454
  • 9
  • 60
  • 108
  • I think it declares `{ int bar; }`, you just can't do anything useful with it. – this Aug 07 '15 at 14:02
  • @David Hammen There is no declarator in this typedef. – Vlad from Moscow Aug 07 '15 at 14:03
  • @this - The standard (see my quote in the question) specifically excludes members of a struct or union. Thus `typedef struct {int bar;};` is illegal. – David Hammen Aug 07 '15 at 14:04
  • @DavidHammen { int bar; } is the declarator, in my opinion. – this Aug 07 '15 at 14:06
  • 1
    @VladfromMoscow - My take is that the quoted text in the question pertains to a declaration statement. As a statement, `typedef struct foo {int bar};` certainly does declare something. It just doesn't declare a target for the typedef. – David Hammen Aug 07 '15 at 14:08
  • 1
    @this - No, it isn't. The parenthetical remark *other than the parameters of a function or the members of a structure or union* in the quoted text specifically excludes `{int bar;}` as the declarator. – David Hammen Aug 07 '15 at 14:10
  • Regarding the closure votes, how can this question possibly be too broad? It is a yes-no question: Must a compliant implementation issue a diagnostic for `typedef struct foo {int bar};` ? – David Hammen Aug 07 '15 at 16:30
  • What this really shows is that a struct should not be typedef'd – user3629249 Aug 08 '15 at 13:40
  • `typedef struct x {...};` is the same as `struct x {...};` – M.M Aug 08 '15 at 14:09
  • @user3629249 it doesn't show that at all – M.M Aug 08 '15 at 14:09
  • I think this is a duplicate: http://stackoverflow.com/questions/6399898/is-the-typedef-name-optional-in-a-typedef-declaration . No idea why there are "too broad" votes – M.M Aug 08 '15 at 14:11

3 Answers3

2

In the quote you cited there is written that a declaration shall declare among other things a tag.

So this declaration

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

simply declares struct student_s and equivalent to declaration without the typedef specifier

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

It does does not introduce a typedef name in the scope.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I understand what this code does, that it does not introduce a typedef name. This does not answer the question. Does failing to introduce a typedef name in and of itself qualify as a violation of a syntax rule or constraint and hence must result in a diagnostic (5.1.1.3 Diagnostics). – David Hammen Aug 07 '15 at 14:39
  • @David Hammen What?!!! I showed that it is a correct declaration. What is the problem with you? – Vlad from Moscow Aug 07 '15 at 14:43
  • Vlad, sorry, I didn't read your answer that way. Upon re-reading, I see that that is exactly what you are saying. – David Hammen Aug 07 '15 at 14:46
1

6.7.1 Storage class specifiers defines typedef as a storage class specifier with the following comment : The typedef specifier is called a ‘‘storage-class specifier’’ for syntactic convenience only;

And 6.7 Declaration contains:

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

First constraint is : A declaration shall declare at least a declarator (other than the parameters of a function or the members of a structure or union), a tag, or the members of an enumeration

As the init-declarator-list is optional in a declaration, provided 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 with no init-declarator. But as the type-specifier declares internally a tag (foo) the constraint is respected.

My conclusion is that such a construct is valid and only produces warning on compilers.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • There is no declarator. foo is a structure tag. – Vlad from Moscow Aug 07 '15 at 14:32
  • @David Hammen And I wrote this in my answer. – Vlad from Moscow Aug 07 '15 at 14:36
  • @SergeBallesta - I'm going to wait a while before accepting an answer, but this is my take as well. If someone could cite chapter and verse from any version of the C standard that says that `typedef struct foo {int bar;}` is illegal, I'd accept that. But I can't find such chapter and verse in the standard. – David Hammen Aug 07 '15 at 14:44
0

this typedef:

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

yields the following:

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

So the syntax is acceptable, but without a declarer, the code is trash

user3629249
  • 16,402
  • 1
  • 16
  • 17