Earlier quoted context omitted.
> Now what happens, if we're trying to define behavior? The cell whose address is three billion greater, mod the size of the address space, now has a value of 20? > If the semantics aren't a direct translation into CPU opcodes, then it's not machine code. Just because the semantics are defined that way doesn't necessarily mean you couldn't make another implementation that obeys those semantics. For instance, QEMU can…
> The cell whose address is three billion greater, mod the size of the address space, now has a value of 20? Cool. It sounds like you figured out a restricted form of pointers for stack variables, since there's no danger of corrupting the code or breaking important invariants elsewhere. Now imaging tightening those restrictions a bit. Instead of wrapping pointers inside the entire stack, wrap/constrict pointers insid…
Yep, that's one approach, though that's just as hard to compile as one that is defined to trap and end execution on an out-of-bounds write.
As I said up-thread, it's possible to define a C dialect without UB, it's just not what most of its users actually want out of the language, since on current hardware it adds significant runtime overhead.
> The machine [...] the compiler
Isn't QEMU both the machine and the compiler (EDIT: perhaps better-put, what's the distinction? They're both just the implementation.) The bytes only need to be unchanged on read from inside the program; if you compile them to something else, that's fine. Prolog programs can introspect with clause/2 and it doesn't cause trouble there.