| Looks to me like union-based type-punning in C is indeed "better than C++" (in C++ it's just plain undefined behavior). In C, it looks like the behavior is defined unless you hit a trap representation. https://port70.net/~nsz/c/c11/n1570.html#6.2.6.1p5 > Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. [...] Such a representation is called a trap representation. https://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p3 > A postfix expression followed by the `.` operator and an identifier designates a member of a structure or union object. The value is that of the named member. [Footnote: If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ''type punning''). This might be a trap representation.] I'm fuzzy on exactly what a "trap representation" might be in real life. I have the impression that a signaling NaN isn't. I suspect that a visibly invalid pointer value on a CHERI-like or ARM64e-like platform might be. Anyway, my impression is that sane platforms don't have trap representations, so indeed, you have to go out of your way to contrive a situation where C's paper standard would not define type-punning (whether union-based or pointer-cast-based) to have the "common-sense" physical behavior. Again this is different from C++, where both union-based type-punning and pointer-cast-based type-punning have UB, full stop: https://eel.is/c++draft/expr.prop#basic.lval-11 > An object of dynamic type Tobj is _type-accessible_ through a glvalue of type Tref if Tref is similar to Tobj, a type that is the signed or unsigned type corresponding to Tobj, or a char, unsigned char, or `std::byte` type. > If a program attempts to access the stored value of an object through a glvalue through which it is not type-accessible, the behavior is undefined. |