Search code examples
c++template-meta-programmingvoid-pointersis-emptyvoid-safety

Address of an empty base optimized subobject


Let's say that I have a value:

int i = 0;

And an empty class eligible for being empty-base optimized:

struct Empty{
  // stuff that passes
  // static_assert( std::is_empty<Empty>::value );
 };

Is it legal to:

Empty& e = *reinterpret_cast<Empty*>(reinterpret_cast<void*>(&i)); //?
// do stuff with e

Solution

  • According to this online C++ standard draft, a cast from one pointer type to a different pointer type and then back is conditionally valid:

    5.2.10 Reinterpret cast

    (7) Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value.

    This means, that the cast per se from int* to Empty* is valid as long as Empty does not have stricter alignment requirements than int, and you can later cast back to int*.

    Note, however, that this does not mean that you may access/dereference the Empty*-object (as it isn't an Empty-object to which the pointer points).

    So the pure cast is OK, but dereferencing it then yields UB.