My understanding, for a long time now, was that a C++ translation unit, after the preprocessor has run, is a sequence of declarations (let me remind that any definition is also a declaration).
Many people have argued with this statement but no one has ever given a counterexample. But I myself found this 开发者_StackOverflow中文版example which troubles me:
int x; //declaration
; // ??? EMPTY DECLARATION?
int main() //dec
{ //la
} //ration
This compiles fine with MSVC and online comeau. I know the standard defines an empty statement but I never heard of an empty declaration. So, I see three options:
- My understanding is correct and the standard defines an empty declaration
- My understanding is correct but the standard doesn't define empty declarations and the above translation is ill-formed
- My understanding is incorrect, i.e. a C++ TU is not a sequence of declarations
Please help me dissolve my doubts. Thanks
Your understanding is correct and the standard (or at least Stroustrup) does define an empty declaration.
EDIT: It seems this answer is wrong (there's a semantic rule on the standard - but not on the book, as far as I can tell - that prohibits both decl-specified-seq
and init-declarator-list
of being empty at the same time). See Charles Bailey's answer.
n "The C++ Programming Language", appendix A, section A.4:
A program is a collection of
translation-unit
s (...). Atranslation-unit
, often called a source file, is a sequence ofdeclaration
s:
translation-unit:
declaration-seq_opt
opt
means the production is optional. In this rule, it means an empty translation unit is valid.
Section 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 ;
So declaration-seq
is a sequence of at least one declaration
. A declaration
can, amongst other things, be a block-declaration
, which in turn produces simple-declaration
. As both the decl-specified-seq
and init-declarator-list
non-literals are optional, ;
is a valid declaration.
An empty-declaration is allowed in (the current draft of) C++0x at file scope (and namespace scope and other places where a declaration is allowed) and it is just a semicolon. It is a standalone grammatical entity.
In C++03 a lone semicolon is not allowed where only a declaration is expected. Although it might appear that a simple-declaration might be able to reduce to just a semicolon an explicit rule disallows this.
7 [dcl.dcl] / 3
In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (clause 9) or enumeration (7.2), that is, when the decl-specifier-seq contains either a class-specifier, an elaborated-type-specifier with a class-key (9.1), or an enum-specifier.
In short this implies that the init-declarator-list can be omitted only when the decl-specifier-seq is not omitted.
精彩评论