Solution 2 is portable - type punning through unions has always been legal in C99, and it was made explicit with TC3, which added the following footnote to section 6.5.2.3:
If the member used to access 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.
Annex J still lists it as unspecfied behaviour, which is a known defect and has been corrected with C11, which changed
The value of a union member other than the last one stored into [is unspecified]
to
The values of bytes that correspond to union members other than the one last stored
into [are unspecified]
It's not that big a deal as the annex is only informative, not normative.
Keep in mind that you can still end up with undefined behaviour, eg
- by creating a trap representation
- by violating aliasing rules in case of members with pointer type (which should not be converted via type-punning anyway as there need not be a uniform pointer representation)
- if the union members have different sizes - only the bytes of the member last used in a store have specified value; in particular, storing values in a smaller member can also invalidate trailing bytes of a larger member
- if a member contains padding bytes, which always take unspecified values
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…