casting between 2 layout compatible types

69 Views Asked by At

I'm a quite confused about whether or not it's possible to cast an object of a certain type to another type with the same layout. I am aware that supposedly similar questions have been posted on Stack Overflow but some are answered in the negative, while others are not, answers given based on different parts of the standard, which adds to the confusion. For example:

(1) Can you reinterpret_cast between types which have the same representation? -> answers NO
(2) Safety of casting between pointers of two identical classes? -> answers YES

And so I'd like to clarify, on the one hand, the specifications of the standard that state what is feasible and what leads to undefined behavior, but also, and above all, the consequences that such practice may have from the compiler's point of view (I'm thinking, for example, about strict aliasing rules and type-based optimizations).

Assuming 2 structs A and B with the same standard layout:

struct A { int i; float x; }
struct B [ int j; float y; }

Both (1) and (2) accepted answers state that casting an object of type A to type B is legal:

A a { 1, 2.3 };
auto& b = reinterpret_cast<B&>(a);  // ok

However, (1) states that trying to access any member of a trough reference b is undefined behavior, violating the strict aliasing rules. (The answer does, however, mention a part of the standard that has since been updated and no longer seems appropriate to confirm the author's answer, if it ever was.)

While (2) states that it is perfectly legal, since both structures have the same standard layout.

auto ai = b.j;  // UB for (1) while OK for (2)

So who's right here ? and :

  • If (1) is right, which part of the standard states that accessing a.i via b.j is UB ? What is the risk of such a practice from the compiler's point of view (assuming strict aliasing is enabled) ? (A detailed description of what could happen would be appreciated.)
  • If (2) is right, at least for the C++11 standard, is it still right for C++17 and above ? Is there any risk that some compilers assume that b cannot be modified through a considering strict aliasing rules ?
0

There are 0 best solutions below