It may be strictly UB, but given that any operating system written in C relies on this behavior being well-defined (e.g. the container_of macro widely used in the Linux kernel) you're probably pretty safe.
Note that there is sort of an active war between the OS folks, who are probably the main users of pure C nowadays, and the UB nazis among the compiler folks who are mostly worried about efficiently optimizing complex template code in C++ and don't care whether their computers continue to run :-)
The linux kernel compiles with no strict aliasing, so kernel code is unaffected. In userspace this is still dodgy, strict aliasing does affect generated code, and correctness of code that relies on UB this way.
A pragmatic solution would be attributes that allowed declaring that certain pairs of types that are allowed to alias with each other. It would even be better if the C and C++ standards provided facilities for this, although it can be challenging to rigurously fit into the object model.
Note that there is sort of an active war between the OS folks, who are probably the main users of pure C nowadays, and the UB nazis among the compiler folks who are mostly worried about efficiently optimizing complex template code in C++ and don't care whether their computers continue to run :-)