【问题标题】:Why are empty declarations allowed?为什么允许空声明?
【发布时间】:2017-01-26 19:23:59
【问题描述】:

为什么 C 允许空声明?它们都在语法级别明确允许,并且仅在编译时生成警告。

来自 C 标准附件 A 的产生式 declaration 在语法级别允许它:

declaration
    = declaration_specifiers , ";"
    | declaration_specifiers , init_declarator_list , ";"
    | static_assert_declaration
    ;

(被我改成了EBNF

【问题讨论】:

  • 因为它们有用吗? struct tagS { int x; }; 正式声明不是空的吗?
  • 您在看什么版本的标准? C11 只显示第二个和第三个选项。
  • @BenVoigt 对!是的,这正式是一个空的声明。结构仅作为声明说明符 => type_specifier => struct_or_union 说明符处理。
  • @Leandros:很难将“你必须至少做一件不平凡的事情,但它可以在说明符中或在声明符列表中”作为语法结构来捕捉。 ..所以这是一个非语法语法规则。见stackoverflow.com/a/33273777/103167
  • @dbush C11 完全显示了上面显示的内容。 init_declarator_list 被标记为可选。

标签: c language-lawyer


【解决方案1】:

C 不允许空声明。见https://stackoverflow.com/a/33273777/103167

但它确实允许没有任何声明符的声明,只有说明符,只要这些说明符创建一个类型标记。例如:

/* here begins the specifier */
struct tagS /* <-- there's the tag */
{
   int x;
} /* here ends the specifier */
/* no declarators */
;

这是定义用户定义类型的结构的一种非常有用且合法的方式。

这就是为什么语法必须将声明符列表指定为可选的原因。

【讨论】:

  • 我的困惑不是来自结构声明,而是因为简单的int; 是一个有效的声明。
  • @Leandros:它无效,因为它既没有声明符也没有标签,也没有定义任何枚举成员。请参阅链接的答案。
  • 虽然在语义上无效,但在语法级别上是有效的。
  • @Leandros int; 在语法上不是一个有效的声明,因为禁止它的约束违反具有纯粹的语法解释,就像禁止 unsigned double 的声明一样。规则是声明必须至少有一个声明符、一个标签或枚举数。这些是语法片段;实际上,这是一条语法规则。可以编写一套更复杂的语法规则来代替这个约束规则。
  • 也就是说,语法可以有单独的规则(1)一个没有标签的结构声明,但至少有一个强制声明符:(2)一个带有标签和可选声明符的结构声明; (3) 带有可选声明符的枚举声明,(4) 具有至少一个声明符的非结构/联合、非枚举说明符。
猜你喜欢
  • 2018-08-15
  • 1970-01-01
  • 2021-02-02
  • 2017-09-04
  • 2014-12-02
  • 2015-02-20
  • 2020-08-10
  • 2018-08-21
相关资源
最近更新 更多