Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
483 views
in Technique[技术] by (71.8m points)

language lawyer - Program being compiled differently in 3 major C++ compilers. Which one is right?

As an interesting follow-up (not of big practical importance though) to my previous question: Why does C++ allow us to surround the variable name in parentheses when declaring a variable?

I found out that combining the declaration in parentheses with injected class name feature may lead to surprising results regarding compiler behavior.

Take a look at the following program:

#include <iostream>
struct B
{
};

struct C
{
  C (){ std::cout << "C" << '
'; }
  C (B *) { std::cout << "C (B *)" << '
';}
};

B *y = nullptr;
int main()
{
  C::C (y);
}
  1. Compiling with g++ 4.9.2 gives me the following compilation error:

    main.cpp:16:10: error: cannot call constructor 'C::C' directly [-fpermissive]
    
  2. It compiles successfully with MSVC2013/2015 and prints C (B *)

  3. It compiles successfully with clang 3.5 and prints C

So obligatory question is which one is right? :)

(I strongly swayed towards clang version though and msvc way to stop declaring variable after just changing type with technically its typedef seems kind of weird)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...