ARTICLE AD BOX
It's UB, although it seems like it shouldn't be.
Two unrelated types can be layout compatible (as they are here) when they're standard layout and have a common initial sequence comprising all their members.
Type-punning layout compatible types via a union is explicitly permitted.
A union and its members are also pointer-interconvertible.
In general you'd think any A* could really be the A member of some union AB { A a; B b; }, and converting to AB* and thence to B* would be absolutely fine (still assuming they're all standard-layout and A, B are layout-compatible).
However, the equivalent type-punning via reinterpret_cast is not (so far as I can see) permitted, even though it should intuitively be identical, and is therefore UB.
Practically this means that although a naive compiler would be expected to just work, the optimizer may misbehave as in other UB.
68.6k6 gold badges100 silver badges143 bronze badges
This is undefined behavior in standard C++, even if all your static_assert checks pass.
Your checks only prove that the two types have the same size, alignment, and memory layout, but the C++ object model is stricter than just same size + same layout.
According to the standard, an object can only be accessed throught its own type.
In your code, A and B are different and unrelated types.
So, accessing an object of type A through a B* pointer breaks the strict aliasing rule.
611k36 gold badges520 silver badges876 bronze badges
Explore related questions
See similar questions with these tags.
