Rather than trying to define all of the behaviors necessary to accomplish every plausible task, the authors of the C and C++ Standards instead allow implementations to support various useful behaviors or not, at their leisure, on the presumption that compiler writers will be able to know and support their customers' needs far better than the Committee ever could.
If one is targeting a platform where all pointers are the same size and have the same representation (true of nearly all implementations for current processor and controller designs), one ensures that any pointer used to access an object of a particular type satisfies the platform's alignment requirements for that type (true if the pointer is a multiple of the size of the largest primitive), and one uses a compiler configuration that is specified to support straightforward type punning patterns (e.g. -fno-strict-aliasing
on clang or gcc), then type punning code will work as expected on that compiler configuration. Such code will not be portable to all other implementations or configurations, but portability is just one factor upon which the quality of code should be judged. If code will run efficiently and correctly on all C implementations where it will be used, replacing it with code that is slower and/or harder to read purely for purposes of making it "portable" would not be an improvement.
Incidentally, every compiler configuration I've tested either uses an abstraction model that supports useful type-punning constructs beyond those mandated by the Standards, or fails to uphold all of the memory-recycling constructs for which the Standard mandates support. It would be impossible for a compiler to behave as specified in all cases where the Standard defines behavior without also behaving in a fashion consistent with writing and reading object representations in many cases where the Standard imposes no requirements; presumably the authors of the Standard expected compilers to accommodate that difficulty by behaving usefully in more cases than required by the Standard, but when optimizations are enabled, clang and gcc prioritize "optimization" over correctness.