While you can't get untyped space on the stack, it is explicitly permitted for objects of character type to alias objects of other types. I don't see how effective_type_3.c has undefined behavior.
The aliasing rule isn’t symmetric: you can access objects originally declared as types other than char using char pointers, but you can’t access objects originally declared as char using non-char pointers. (And malloc()ed buffers are neither of the above and have their own rule.) Here’s a blog post explaining it in more detail: