Compilation error in clang ( related to copy constructor )

Hi all,
This is regarding this program

#include
#include

struct A {
A(){};
A(const A &) { std::cout << “A’s Copy Constructor” << std::endl; }
};

struct B : A
{
B(int) { std::cout << “Constructor” << std::endl; }
B(const B &) { std::cout << “Copy Constructor” << std::endl; }
B(A) { std::cout << “Special Constructor” << std::endl; }
};

void foo(B){}

int main()
{
foo(0);
return 0;
}

The output of this program is

Constructor

using both gcc and clang

But if the program is slightly different (“const” missing from B’s copy constructor)

#include
#include

struct A {
A(){};
A(const A &) { std::cout << “A’s Copy Constructor” << std::endl; }
};

struct B : A
{
B(int) { std::cout << “Constructor” << std::endl; }
B(B &) { std::cout << “Copy Constructor” << std::endl; }
B(A) { std::cout << “Special Constructor” << std::endl; }
};

void foo(B){}

int main()
{
foo(0);
return 0;
}

Output of gcc is

Constructor

A’s Copy Constructor

Special Constructor

Clang doesn’t compile giving error

"no viable constructor copying parameter of type ‘B’ "

My previous understanding was that gcc tried to use B’s copy constructor but as it has non constant reference argument so it uses A’s copy constructor but even after adding the “const”, I see that “Copy Constructor” is still not printed.
Clang is unable to compile that means it is not even trying to do it using B(A) constructor when const is not present. When it is, then also “Copy Constructor” is not printed.

Please suggest where I might be wrong and why I am observing this behavior.
Any leads will be helpful

Regards,
Chakshu

201410091712808_BEI0XT4N.gif

Here’s what I think is happening:

function foo(B) requires B to have a copy constructor because it’s passing by value.

foo(0) invokes B’s int constructor. It’s working as implicit conversion constructor from int because it isn’t marked as explicit. This temporary is an r-value and you can’t bind a non-const reference to it. So const copy constructor works, non-const doesn’t.

Now I have no idea what gcc is doing, but I don’t think that having A makes any difference at all. Note that I don’t really know the exact rules here, but the error clang reports looks reasonable.

201410091712808_BEI0XT4N.gif