Memory corruption is pretty undefinable. Imagine writing data through a wild pointer. The program might segfault immediately, or compute a wrong result but not crash, or crash at an arbitrary later point, or delete all your files, or...
It makes no sense to try to enumerate all that might happen, so this cannot really be implementation defined (where the implementation must document what will happen).
Then a particular ABI could say "if your pointer overflows (by a our system specific meaning of overlow) then you have a bad pointer". Merely doing a pointer increment just gets you implementation-defined behaviour. The UB only happens if you plough on.
Such a setup wouldn't do much to save us from pointer bugs. But it would make optimizers more predictable.
Could somebody provide me with an example of truly undefinable behavior? (Perhaps data races?)