Resolving Ambiguous Statements in C++

There are situations in C++ where a statement can be parsed as both a declaration and as an expression. Specifically, a declaration can look like a function call in certain cases. The compiler resolves these ambiguities by applying the following rules to the whole statement:

In some cases, C++ syntax does not disambiguate between expression statements and declaration statements. The ambiguity arises when an expression statement has a function-style cast as its leftmost subexpression . (Note that, because C does not support function-style casts, this ambiguity does not occur in C programs.) If the statement can be interpreted both as a declaration and as an expression, the statement is interpreted as a declaration statement.

Note: The ambiguity is resolved only on a syntactic level. The disambiguation does not use the meaning of the names, except to assess whether or not they are type names.

The following expressions disambiguate into expression statements because the ambiguous subexpression is followed by an assignment or an operator. type_spec in the expressions can be any type specifier:

type_spec(i)++;             // expression statement
type_spec(i,3)<<d;          // expression statement
type_spec(i)->l=24;         // expression statement

In the following examples, the ambiguity cannot be resolved syntactically, and the statements are interpreted as declarations. type _spec is any type specifier:

type_spec(*i)(int);         // declaration
type_spec(j)[5];            // declaration
type_spec(m) = { 1, 2 };    // declaration
type_spec(*k) (float(3));   // declaration

The last statement above causes a compile-time error because you cannot initialize a pointer with a float value.

Any ambiguous statement that is not resolved by the above rules is by default a declaration statement. All of the following are declaration statements:

type_spec(a);               // declaration
type_spec(*b)();            // declaration
type_spec(c)=23;            // declaration
type_spec(d),e,f,g=0;       // declaration
type_spec(h)(e,3);          // declaration

Another C++ ambiguity between expression statements and declaration statements is resolved by requiring an explicit return type for function declarations within a block:

a();         // declaration of a function returning int
             // and taking no arguments
void func()
{
   int a();  // declaration of a function
   int b;    // declaration of a variable
   a();      // expression-statement calling function a()
   b;        // expression-statement referring to a variable
}

The last statement above does not produce any action. It is semantically equivalent to a null statement. However, it is a valid C++ statement.



Cast Expressions