Clang seems to prefer copy-ctor

Hiya,

When initialising class members with braces, it seems Clang doesn’t have the same behaviour as GCC/MSVC. GCC and MSVC try to use the initializer-list-constructor if defined, where Clang appears to be using the copy-constructor.

My guess is that copy elision is what might be causing this behaviour. Is it correct, or is this a bug?

For the way I’m using it, the initializer-list-constructor behaves quite differently to the copy-constructor and triggered completely different behaviour between Clang and the other compilers.

Super keen to hear any thoughts.

Cheers,
Matt

Repro case:

struct ContainedObj {
ContainedObj() = default;
ContainedObj(ContainedObj const& other) { std::cout << this << “: copy ctor” << std::endl; }
ContainedObj(std::initializer_list) { std::cout << this << “: il ctor” << std::endl; }
};

struct WithBraces {
ContainedObj mContained;
explicit WithBraces(ContainedObj const& contained) : mContained{contained} {}
};

struct WithBrackets {
ContainedObj mContained;
explicit WithBrackets(ContainedObj const& contained) : mContained(contained) {}
};

ContainedObj a;
WithBrackets b(a);
WithBrackets c{a};
WithBraces d(a);

WithBraces e{a};

Output on MSVC 2017 and g++ 6.3.0:

00F3FA6B: copy ctor
00F3FA5F: copy ctor
00F3F887: copy ctor
00F3FAF3: il ctor
00F3F887: copy ctor
00F3FA47: il ctor

Clang output:
0x7ffeefbff580: copy ctor
0x7ffeefbff578: copy ctor
0x7ffeefbff570: copy ctor
0x7ffeefbff568: copy ctor

Hiya,

When initialising class members with braces, it seems Clang doesn’t have the same behaviour as GCC/MSVC. GCC and MSVC try to use the initializer-list-constructor if defined, where Clang appears to be using the copy-constructor.

My guess is that copy elision is what might be causing this behaviour. Is it correct, or is this a bug?

https://clang.llvm.org/cxx_dr_status.html#2137