结构声明中是否允许使用额外的分号?

N. *_*aul 6 c gcc language-lawyer

这个问题仅仅是好奇心.它不是关于空结构.

我偶然发现了一个有趣的错字

struct {
     int member1; /*comment*/ ; /* <-- note the ';' */
     int member2;
} variable[] = { /* initializers */ };
Run Code Online (Sandbox Code Playgroud)

编译器(xc32,派生自gcc)接受,没有任何投诉.当然,我纠正了这一点,但软件在纠正之前和之后运行顺利,而且额外的;看似没有问题.然后,我尝试了;;;结构定义中的各种长度,它们似乎对功能和功能都没有任何区别sizeof.所以在struct任何序列中;;;;似乎都等同于单一;.

我在规范中找不到关于结构/联合的这种"空成员"的任何内容,既不允许它们也不允许它们被禁止.对我来说,似乎语法拒绝了他们.这与;编译单元顶层的"空声明"形成对比,标准明确禁止该标准,并且功能中的"空"声明;是明确允许的语言特征.

有谁知道这种行为?它是编译器特定的还是C规范以某种方式容忍这样的空结构成员?

Lun*_*din 8

语法在C11 6.7.2.1中指定

struct-declaration:
specifier-qualifier-list struct-declarator-listopt ;
static_assert声明

最后有1个分号,因此这是唯一允许的语法.你不能跳过分号,你不能添加额外的分号.就是这样.

(但是,您可以在结构声明中使用静态断言,来自C11.)

  • @ Jean-FrançoisFabre我注意到gcc做了,这就是为什么编译`-pedantic-errors`是一个好主意,如果严格的C标准一致性很重要.添加额外的分号将使代码非标准且不可移植. (2认同)

Jea*_*bre 4

标准没有提到这一点,只是一个gcc容差。参见6.7.2.1:

struct-or-union-specifier:
              struct-or-union identifieropt { struct-declaration-list }
              struct-or-union identifier
struct-or-union:
             struct
             union
struct-declaration-list:
             struct-declaration
             struct-declaration-list struct-declaration
struct-declaration:
             specifier-qualifier-list struct-declarator-listopt ;
             static_assert-declaration
specifier-qualifier-list:
            type-specifier specifier-qualifier-listopt
            type-qualifier specifier-qualifier-listopt
Run Code Online (Sandbox Code Playgroud)

(type-specifier且type-qualifier不能为空,具体参见标准中的相关章节。)


一些编译器(例如 gcc)可以容忍额外的分号,但-Wpedantic选项显示这只是一种容忍:

struct foo {
    int a;
    ;;;
};

int main() {
    ;;;
}
Run Code Online (Sandbox Code Playgroud)

使用 -pedantic 选项,gcc 抱怨的不是主要的空语句,而是结构声明的额外分号。

<source>:3:5: warning: extra semicolon in struct or union specified [-Wpedantic]
     ;;;
     ^
<source>:3:6: warning: extra semicolon in struct or union specified [-Wpedantic]
     ;;;
      ^
<source>:3:7: warning: extra semicolon in struct or union specified [-Wpedantic]
     ;;;
Run Code Online (Sandbox Code Playgroud)

其他编译器可能不太友好,因此必须修复拼写错误,因为它不会带来任何有用的东西。