`typedef struct foo {int bar};`

时间:2015-08-07 13:47:48

标签: c struct typedef language-lawyer

这个问题来自问题Is a struct {...}; a type or an unnamed variable?

在那个问题上,OP询问了

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

我在问上述合法性。编译包含上述代码的代码时是否需要诊断(或使其更简单,typedef struct foo {int bar;};)?

我认为,从语言律师的角度来看,不需要诊断是合法的。 (旁白:我不主张使用它。它非常值得诊断。如果我错误地编写了类似上面的代码,我非常希望编译器警告我。)


C11标准的第6.7节规定了声明的语法: declaration-specifiers init-declarator-list opt ;注意 init-declarator -list 是可选的。这可能导致人们认为typedef int;有效。这不是因为标准也说

  

除static_assert声明之外的声明应至少声明一个声明符(除了函数的参数或结构或联合的成员),标记或枚举的成员。

因此typedef int;typedef struct {int bar};是非法的,因为它们不声明声明符,标记或枚举成员。

另一方面,在我看来typedef struct foo {int bar;};是合法的,因为它确实声明了一些东西。特别是,它声明并定义了struct标记foo

上述推理是否正确?

3 个答案:

答案 0 :(得分:2)

在你引用的引文中,有人声称声明应在其他方面声明标签。

所以这个宣言

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

简单地声明struct student_s并且等同于没有typedef说明符的声明

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

它没有在范围中引入typedef名称。

答案 1 :(得分:1)

6.7.1存储类说明符将typedef定义为具有以下注释的存储类说明符: typedef说明符称为“存储类说明符”,以方便语法 仅;

6.7声明包含:

语法:

  • 声明:
    • declaration-specifiers init-declarator-list opt
  • 声明-指示符:
    • storage-class-specifier declaration-specifiers opt
    • type-specifier declaration-specifiers opt
    • type-qualifier声明说明符 opt
    • function-specifier declaration-specifiers opt
  • 初始化声明符列表:
    • 初始化声明符
    • init-declarator-list,init-declarator
  • 初始化声明符:
    • 声明符
    • declarator = initializer

第一个约束是:声明应至少声明一个声明者 (除了函数的参数或 结构或联合的成员),标记或枚举的成员

由于init-declarator-list在声明中是可选的,如果声明了声明符或标记,我会说typedef struct foo {int bar;};是一个声明被分解为storage-class-specifier type-specifier而没有init-declarator的声明。但是,由于类型说明符在内部声明了一个标记(foo),因此尊重该约束。

我的结论是这样的构造是有效的,只会在编译器上产生警告。

答案 2 :(得分:0)

此typedef:

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

产生以下结果:

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

所以语法是可以接受的,但没有声明者,代码就是垃圾