“typedef struct foo {int bar};”的合法性



这个问题来自于问题是struct{…};类型还是未命名的变量?

在那个问题中,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-listopt ;注意init-declarator-list是可选的。这可能导致人们认为typedef int;是有效的。不是因为标准还规定

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

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

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

以上推理正确吗?

在你引用的这段引文中,有一段写着声明应该声明一个标签。

所以这个声明

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

简单地声明struct student_s和等价于没有类型定义说明符的声明

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

它没有在作用域中引入类型定义名。

6.7.1存储类说明符将typedef定义为存储类说明符,并附有以下注释:为了语法方便,typedef说明符称为"存储类说明符",

和6.7声明包含:

语法:

  • 声明:
    • declaration-specifiers init-declarator-list <子>选择
  • declaration-specifiers:
    • storage-class-specifier declaration-specifiers <子>选择
    • type-specifier declaration-specifiers <子>选择
    • type-qualifier declaration-specifiers <子>选择
    • function-specifier declaration-specifiers <子>选择
  • init-declarator-list:
    • init-declarator
    • init-declarator-list, init-declarator
  • init-declarator:
    • 说明符
    • 声明器=初始化器

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

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

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

this typepedef:

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]

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

最新更新