c++c++11language-lawyershared-ptrvirtual-inheritance

Copying virtual base class results in losing shared_ptr owned object


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?


Solution

  • d = D( d ) invokes D's implicitly-defined move assignment operator (with a temporary copy of d as a source of assignment).

    [class.copy.assign]/12:

    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:

    which leads to the observed outcome.