I don't understand the "undefined behavior" bandwagon.
1. We have a perfectly defined list of "undefined behaviors".
2. Said list also happens to be relatively small and scoped.
3. "Undefined behaviors" exist because the language can't make certain runtime guarantees which are largely dependent on compiler/os/platform/hardware-specific promises. If you have to, just roll in your own runtime checks. C won't force those on you...