As far as I can tell this is covered in the draft C++ standard section 6.8
Ambiguity resolution which says that there can be an ambiguity between expression statements and declarations and says:
There is an ambiguity in the grammar involving expression-statements
and declarations: An expression statement with a function-style
explicit type conversion (5.2.3) as its leftmost subexpression can be
indistinguishable from a declaration where the first declarator starts
with a (. In those cases the statement is a declaration. [ Note: To
disambiguate, the whole statement might have to be examined to
determine if it is an expression-statement or a declaration. This
disambiguates many examples. [ Example: assuming T is a
simple-type-specifier (7.1.6),
and gives the following examples:
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
and then says:
The remaining cases are declarations. [ Example:
class T {
// ...
public:
T();
T(int);
T(int, int);
};
T(a); // declaration
T(*b)(); // declaration
T(c)=7; // declaration
T(d),e,f=3; // declaration
extern int h;
T(g)(h,2); // declaration
—end example ] —end note ]
It seems like this case falls into the declaration examples in particular the last example seems to make the case in the OP, so gcc
would be correct then.
Relevant section mentioned above 5.2.3
Explicit type conversion (functional notation) says:
[...] If the type specified is a class type, the class type shall be complete. If the expression
list specifies more than a single value, the type shall be a class with a suitably declared constructor (8.5, 12.1),
and the expression T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2, ...); for some
invented temporary variable t, with the result being the value of t as a prvalue.
and 8.3
Meaning of declarators which says:
In a declaration T D where D has the form
( D1 )
the type of the contained declarator-id is the same as that of the
contained declarator-id in the declaration
T D1
Parentheses do not alter the type of the embedded declarator-id, but
they can alter the binding of complex declarators.
Update
I was originally using N337 but if we look at N4296 section 6.8
was updated an it now includes the following note:
If the statement cannot syntactically be a declaration, there is no ambiguity, so this rule does not
apply.
which means that gcc
is incorrect since:
foo x ("bar")("baz");
can not be a valid declaration, I originally interpreted paragraph 2
as saying if you case begins with any of the following then it is declaration, which is perhaps how the gcc
implementor interpreted as well.
I should have been more suspicious of paragraph 2
since the only normative part of paragraph 2
really said nothing with respect to paragraph 1
and seems to place a requirement on an example which is not normative. We can see that that statement form paragraph 2
is now actually a note which makes much more sense.
As T.C. noted below, paragraph 2
was actually never normative, it just appeared that way and he linked to the change that fixed it.