GCC and Clang do not perform C++17’s guaranteed copy elision when a base class constructor is called; see this question and the corresponding Clang bug report for details.
In response to the bug report, Richard Smith states:
This is a defect in the standard wording. Copy elision cannot be guaranteed when initializing a base class subobject, because base classes can have different layout than the corresponding complete object type.
Under what circumstances can a base class have a “different layout than the corresponding complete object type” in a way that makes guaranteed copy elision impossible? Is there a concrete example that illustrates this?
Whenever virtual inheritance is involved.
Example:
struct A {
int a;
A (int a) : a(a) {}
};
struct B: virtual A {
B() : A(0) {}
};
B makeB { return B(); }
struct C : B {
C() : B(makeB()), A(42) {}
};
The C
constructor initialises its A
subobject, so the B
constructor cannot. How would makeB
know whether it should initialise A
?
Copy elision is still theoretically possible in this case. The implementation would need to transparently create two binary versions of makeB
, or add an invisible argument to makeB
(i.e. use a technique employed for constructors themselves) so that it could make B
with or without initialising A
. This would seem to require an incompatible change in the ABI however.
There may or may not be a defect in the standard. This situation probably was not foreseen by the committee. If it was, I would be happy to read the discussion, as it surely must have left a paper trail. So the intent is unclear until there's a clarification from the committee. If the intent is to require copy elision in this case, ABI incompatibility be damned, then further changes to the standard might be required (unless the committee had foreseen the situation and made sure everything is compatible with it, in which case there should be some kind of paper trail again).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With