3

I saw this snippet on Meeting C++ (@meetingcpp)

Following code compiles fine on clang and MSVC (Can try here) but fails on gcc and icc.

#include <iostream>
using namespace std;

struct B {};
struct C {
    C() { cout << "C()\n"; }
    C(B *) { cout << "C(B *)\n"; }
};

B *p = nullptr;

int main() {
    C::C(p);
    return 0;
}

Is this a known bug in Clang and MSVC or there are any chances this code may be legal?

Type of p is B *, but C::C should not compile?

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100

2 Answers2

3

According to the standard 12.1/p2 Constructors [class.ctor] (Emphasis Mine):

A constructor is used to initialize objects of its class type. Because constructors do not have names, they are never found during name lookup; however an explicit type conversion using the functional notation (5.2.3) will cause a constructor to be called to initialize an object. [ Note: For initialization of objects of class type see 12.6. — end note ]

Thus, you can't call a constructor directly, because constructors do not have names and they are never found during name lookup.

Consequently, GCC is conforming while CLANG and VC++ are not.

101010
  • 41,839
  • 11
  • 94
  • 168
  • 2
    Ironically, the `C::C` in this case *does* refer to the constructor and *not* to the injected-class-name, and that's the reason why it's an error. – dyp Dec 17 '15 at 07:49
3

This is a known bug in Clang, bug reports 23253, 23254 and 13403 are all reports of the issue. Ironically, this question is actually a duplicate of Program being compiled differently in 3 major C++ compilers. Which one is right?.