C++翻译单元的语法

Arm*_*yan 9 c++ grammar declaration

我很长一段时间以来的理解是,在预处理器运行之后,C++转换单元是一系列声明(让我提醒任何定义也是一个声明).

很多人都赞同这个说法,但没有人给出反例.但我自己发现这个让我烦恼的例子:

int x;       //declaration

;            // ??? EMPTY DECLARATION?

int main()   //dec
{            //la
}            //ration
Run Code Online (Sandbox Code Playgroud)

这与MSVC和在线照片很好地编辑.我知道标准定义了一个空语句,但我从未听说过空声明.所以,我看到三个选择:

  • 我的理解是正确的,标准定义了一个空声明
  • 我的理解是正确的,但标准没有定义空声明,上面的翻译是不正确的
  • 我的理解是不正确的,即C++ TU不是一系列声明

请帮我解除疑惑.谢谢

Ped*_*ino 6

您的理解是正确的,标准(或至少Stroustrup)确实定义了一个空声明.

编辑:似乎这个答案是错误的(标准上有一个语义规则 - 但据我所知,这本书并没有 - 禁止两者decl-specified-seq同时init-declarator-list为空).请参阅Charles Bailey的回答.


n"C++编程语言",附录A,A.4节:

程序是translation-units(...)的集合.A translation-unit,通常称为源文件,是一系列declarations:

translation-unit:
   declaration-seq_opt
Run Code Online (Sandbox Code Playgroud)

opt意味着生产是可选的.在此规则中,它表示空翻译单元有效.

第A.7节:

declaration-seq:
    declaration
    declaration-seq declaration

declaration:
    block-declaration
    (...)

block-declaration:
    simple-declaration
    (...)

simple-declaration:
    decl-specified-seq_opt init-declarator-list_opt ;
Run Code Online (Sandbox Code Playgroud)

所以declaration-seq至少有一个序列declaration.declaration除其他外,A 可以是a block-declaration,而a 又可以产生simple-declaration.由于非文字decl-specified-seqinit-declarator-list非文字都是可选的,因此;是有效的声明.

  • 不是这样,请参见[dcl.dcl]/3."在_simple-declaration_中,只有在声明类或枚举时才能省略可选的_init-declarator-list_ ..."在其中一种情况下_decl-specifier -seq_不能为空.在C++ 0x中仍然如此,但在C++ 0x中还有一个额外的显式_empty-declaration_,因此单独的分号是有效的. (4认同)

CB *_*ley 5

一个空的声明是允许在(目前草案)的C ++ 0x在文件范围内(和命名空间范围,其中一个声明是允许的其他地方),它仅仅是一个分号。它是一个独立的语法实体。

在C ++ 03中,仅在需要声明的地方不允许使用单独的分号。尽管看起来简单声明可能可以简化为分号,但显式规则不允许这样做。

7 [dcl.dcl] / 3

在一个简单的声明,任选的INIT-声明符列表可以仅省略声明类(第9节)或枚举(7.2)时,即,当时DECL说明符-SEQ包含任一类说明符中,阐述了带有类键(9.1)的-type-specifierenum-specifier

简而言之,这意味着仅当不省略decl-specifier-seq时,才能省略init-declarator-list