Grammar of a C++ Translation Unit

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 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

Answers


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.


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-units (...). A translation-unit, often called a source file, is a sequence of declarations:

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.


Need Your Help

VS 2012 MVC - Using one View & Model for both Update and Create functionality

c# asp.net-mvc asp.net-mvc-4 visual-studio-2012

I am new to C# and MVC and am coming into the Visual Studio environment from a PHP background. I'm groping around a little (lot), but getting there. I need help in understanding some essential conc...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.