The C99 standard explicitly says type punning through a union is allowed. This is clarified in TC3 (2007) by the addition of this note in 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.