Unfortunately you have to choose what you want your C compiler to be.
It can be little more than a macro assembler that preserves "the obvious" behavior of undefined constructs on the target platform. Most compilers will do this by default (-O0).<p>Or you can opt into using an optimizing compiler (-O2). But when optimization passes ignore the possibility of undefined behavior with unpredictable results (as explicitly allowed by the standard), you get, well, unpredictable results.<p>Nowadays compilers even offer the "terminating a translation or execution" variant that the standard proposes (-fsanitize=undefined,address). So really, the choice is up to you.<p>But what people really want is of course: keep the undefined behavior that <i>my</i> program happens to use predictable, but given that constraint, optimize as much as possible (=exploit all the <i>other</i> undefined behavior).<p>Example: inlining functions is an acceptable optimization, because of course I'm not intentionally using out-of-bounds pointers to grab the return address from the stack.