Program being compiled differently in 3 major C++ compilers. Which one is right?
Solution 1:
GCC is correct, at least according to C++11 lookup rules. 3.4.3.1 [class.qual]/2 specifies that, if the nested name specifier is the same as the class name, it refers to the constructor not the injected class name. It gives examples:
B::A ba; // object of type A
A::A a; // error, A::A is not a type name
struct A::A a2; // object of type A
It looks like MSVC misinterprets it as function-style cast expression creating a temporary C
with y
as a constructor parameter; and Clang misinterprets it as a declaration of a variable called y
of type C
.
Solution 2:
G++ is correct as it gives an error. Because the constructor could not be called directly in such a format without new
operator. And although your code calls C::C
, it looks like an constructor call. However, according to the C++11 standard 3.4.3.1, this is not a legal function call, or a type name (see Mike Seymour's answer).
Clang is wrong since it even does not call the correct function.
MSVC is something reasonable, but still it does not follow the standard.