https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86886
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> --- Your second example has undefined behaviour, as you blatantly violate the strict aliasing rules, and -Wstrict-aliasing=2 will warn you about it: 86886.c:5:1: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] unsigned short **h = (unsigned short **)&f; ^~~~~~~~ The union example has the same problem, just less blatantly.