Skip to content

Avoid copying inactive union members and breaking class encapsulation for Object

Adam Reichold requested to merge (removed):object-hygiene into master

After closing !38 (closed), I remembered that it is actually UB in C++ (in contrast to C) to access any inactive union member, i.e. for union { double foo; long bar; } you are basically not allowed to copy foo if the union actually contains bar even if their representations match which is in contrast to C which does not explicitly forbid this way of type punning (and GCC even recommending it (for C that is)), c.f. cppreference:

The details of that allocation are implementation-defined, and it's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.

But also, we only zero the union for uninitialized objects where this is wasted effort since we will never access any union member using these values (OBJECT_TYPE_CHECK makes sure of that). And we never copy only the union but always the union and the type, i.e. we can just memcpy the whole Object to move its contents around. (Which the compiler will optimize knowing all the details of both the type representation and memcpy's implementation.)

Also we do not need the the friend declarations for Array, Dict and XRef as while they do manual management (at least the current non-STL Array does), they do not need special privileges as they are just creating and destroying instances of Object, i.e. they can use its normal public constructors/destructors (via placement new where necessary).

Merge request reports