Files
2025-10-25 03:02:53 +03:00

5.1 KiB
Raw Permalink Blame History

[stmt.ambig]

8 Statements [stmt]

8.11 Ambiguity resolution [stmt.ambig]

1

#

There is an ambiguity in the grammar involvingexpression-statements and declarations: Anexpression-statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the firstdeclarator starts with a (.

In those cases thestatement is considered a declaration, except as specified below.

2

#

[Note 1:

If the statement cannot syntactically be adeclaration, there is no ambiguity, so this rule does not apply.

In some cases, the whole statement needs to be examined to determine whether this is the case.

This resolves the meaning of many examples.

[Example 1:

Assuming T is asimple-type-specifier ([dcl.type.simple]),

T(a)->m = 7; // expression-statement T(a)++; // expression-statement T(a,5)<<c; // expression-statement T(*d)(int); // declaration T(e)[5]; // declaration T(f) = { 1, 2 }; // declaration T(*g)(double(3)); // declaration

In the last example above, g, which is a pointer to T, is initialized to double(3).

This is of course ill-formed for semantic reasons, but that does not affect the syntactic analysis.

— end example]

The remaining cases are declarations.

[Example 2: class T {// ...public: T(); T(int); T(int, int);}; T(a); // declaration T(*b)(); // declaration T(c)=7; // declaration T(d),e,f=3; // declarationextern int h; T(g)(h,2); // declaration — end example]

— end note]

3

#

The disambiguation is purely syntactic; that is, the meaning of the names occurring in such a statement, beyond whether they aretype-names or not, is not generally used in or changed by the disambiguation.

Class templates are instantiated as necessary to determine if a qualified name is a type-name.

Disambiguation precedes parsing, and a statement disambiguated as a declaration may be an ill-formed declaration.

If, during parsing, lookup finds that a name in a template argument is bound to (part of) the declaration being parsed, the program is ill-formed.

No diagnostic is required.

[Example 3: struct T1 { T1 operator()(int x) { return T1(x); }int operator=(int x) { return x; } T1(int) { }};struct T2 { T2(int) { } };int a, (*(*b)(T2))(int), c, d;

void f() {// disambiguation requires this to be parsed as a declaration: T1(a) = 3, T2(4), // T2 will be declared as a variable of type T1, but this will not(*(*b)(T2(c)))(int(d)); // allow the last part of the declaration to parse properly,// since it depends on T2 being a type-name} — end example]

4

#

A syntactically ambiguous statement that can syntactically be a declaration with an outermost declarator with a trailing-return-type is considered a declaration only if it starts with auto.

[Example 4: struct M;struct S { S* operator()(); int N; int M; void mem(S s) {auto(s)()->M; // expression, S::M hides ::M}};

void f(S s) {{auto(s)()->N; // expressionauto(s)()->M; // function declaration}{ S(s)()->N; // expression S(s)()->M; // expression}} — end example]