【问题标题】:Are extra semicolons allowed inside struct declarations?结构声明中是否允许使用额外的分号?
【发布时间】:2018-03-28 08:02:23
【问题描述】:

这个问题只是出于好奇。 不是关于空结构的。

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

struct {
     int member1; /*comment*/ ; /* <-- note the ';' */
     int member2;
} variable[] = { /* initializers */ };

编译器(xc32,源自 gcc)没有任何接受 投诉。当然,我纠正了这个,但软件正在运行 前后顺利修正和附加;貌似 不会引起任何问题。然后我在结构定义中尝试了各种长度的;;;,它们似乎对功能都没有影响 也不是sizeof。因此,在struct 中,;;;; 的任何序列似乎都是 相当于单个;

我找不到任何关于结构/联合的“空成员”的信息 在规范中,它们既不被允许也不被允许 不允许。在我看来,语法似乎拒绝了它们。这对比 在编译单元的顶层“空声明”; 标准明确禁止并且函数中的“null”声明; 明确允许的语言功能。

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

【问题讨论】:

  • 但是,普通语句(如x=y+2;puts("aa"); 或块)不能出现在struct 定义中。为什么里面可以出现空的statements,而其他类型的statements却不行?
  • @P.P.不是重复的。这个分号在struct 声明中。 不是空语句。
  • @P.P.这不是真正的重复。 ; 不是声明中的语句。我的回答是没有实际意义的,我已将其删除。
  • @Jean-FrançoisFabre 我已经重新打开它了。
  • 您的实际代码有 3 个迂腐错误...rextester.com/XKKK47051

标签: c gcc language-lawyer


【解决方案1】:

语法在 C11 6.7.2.1 中指定

结构声明:
说明符-限定符-列表 struct-declarator-listopt ;
静态断言声明

末尾有 1 个分号,因此这是唯一允许的语法。您不能跳过分号,也不能添加额外的分号。就是这样。

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

【讨论】:

  • 但是有些编译器会容忍这种情况(并发出警告)
  • @Jean-FrançoisFabre 我注意到 gcc 确实如此,这就是为什么如果严格的 C 标准一致性很重要,使用 -pedantic-errors 编译是一个好主意。添加额外的分号会使代码不标准且不可移植。
  • 我添加了 gcc 缺失位。我希望你不介意(我无法取消删除我对此错误投赞成票的答案,但我认为 lilliscent 评论应该被官方化)
  • @Jean-FrançoisFabre 我确实介意,因为我并不真正关心 gcc 在“gnu poop 模式”下做什么和不做什么。如果要使用 gcc,请始终使用 -std=c11 -pedantic-errors 进行编译,否则编译器有点危险。没有其他 C 编译器接受这一点,我只是尝试了两个不同的(IAR 和 Codewarrior),默认情况下它们会给出编译器错误。
  • 不用担心,我只是做了我的回答 CW(所有错误的赞成票和所有:))并添加了我的一点。随意投反对票:)(抱歉,OP 接受了我的回答……这不是为了这个,因为它是 CW)
【解决方案2】:

标准没有提到这一点,它只是一个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

type-specifiertype-qualifier不能为空,详见标准相关章节)


一些编译器,比如 gcc,允许额外的分号,但是-Wpedantic 选项表明它只是一个容忍:

struct foo {
    int a;
    ;;;
};

int main() {
    ;;;
}

使用 -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]
     ;;;

其他编译器可能不是那么友好,所以必须修正错字,因为它没有带来任何有用的东西。

【讨论】:

  • struct 声明中可以出现什么样的语句? (直觉上,我相信没有)
  • 这是错误的。您指的是与问题无关的复合语句部分。相反,它是declaration 的一部分。额外的分号是pedantically wrong
  • 规范中没有关于声明和分号的具体规定,您是对的。
  • @Jean-FrançoisFabre:旁注:ISO9899 是一个标准,而不仅仅是一个规范。也许他们是你的语言中完美的假朋友(我知道他们是英语/德语)
  • 我第一次在回答中引用规范(标准,抱歉):) 已编辑
猜你喜欢
  • 2018-06-09
  • 2010-10-10
  • 2017-07-19
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2010-09-21
相关资源
最近更新 更多