A colleague at work showed me this program:
#include <iostream>
#include <memory>
struct A {
std::shared_ptr<int> u{ new int };
};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
int main() {
D d;
d = D( d );
std::cout << d.u;
}
which despite initializing shared_ptr
with new int
prints zero. Online demo: https://gcc.godbolt.org/z/n3Kxbc3Pf
I see that it is somehow related to diamond inheritance and common virtual base class.
Does the program have any undefined behavior, or the program is well formed and the standard requires printing zero here?
d = D( d )
invokes D
's implicitly-defined move assignment operator (with a temporary copy of d
as a source of assignment).
It is unspecified whether subobjects representing virtual base classes are assigned more than once by the implicitly-defined copy/move assignment operator.
In this case, if the assignment of the A
base is performed more than once:
std::shared_ptr<int>
in a moved-from state, i.e., empty.shared_ptr
to d.u
, making it empty as well,which leads to the observed outcome.