(And you don't need casts when converting between void pointers and data pointers)
It might be undefined in the sense that a language lawyer might care, but for any sane implementation it’s completely valid.
In practice though, it works pretty much everywhere in my experience.