I'm working with a union which has a member that is a class that uses diamond inheritance, but the program encounters a segmentation fault upon assignment to this member.
My suspicion is that I need to add some copy constructors, but after multiple attempts, the correct way to do this still evades me.
I've included a minimal, reproducible example here.
struct Base
{
Base() : a(0) {}
Base(int x) : a(x) {}
int a;
};
struct Derived1 : virtual public Base
{
Derived1() {}
};
struct Derived2 : virtual public Base
{
Derived2() {}
};
struct Final : public Derived1, public Derived2
{
Final() {}
};
union Example
{
Final value;
int i;
};
int main()
{
Example example{ Final() };
example.i = -1;
/* Segfault on the line below.
* If the above line
example.i = -1;
* is removed, the segfault is not encountered. */
example.value = Final();
}
My thanks to anyone who knows how to do this.
Since the Base
class is virtual, most likely there are some internal control structures, which become destroyed, when you assign
example.i = -1;
When you recreate value
, e.g.
new(&example.value) Final();
example.value = Final();
before the assignment, the segmentation fault goes away. Although, I wouldn't recommend this hack.
As already mentioned in the comments, a std::variant
would be more appropriate, if you have C++17 available. The example would then become
std::variant<Final, int> example{ Final() };
example = -1;
example = Final();