I think the most important point of Friendly C is not to define the behaviour for what would otherwise be undefined, but to define a behaviour; from this point of view, it would be unnecessary to argue over the examples he mentions like memcpy() vs memmove() and integer shifting --- it only suffices that every implementation define the behaviour, and what that behaviour precisely is can differ between them. A lot dif…
You have to look deeper for the OOB array access question. For example, imagine I have code like this: if (a > 1) b++; array[b] = 0; c = a + 10; Under your suggested semantics, can the compiler use the value loaded from `a` at the point of the if() statement to calculate `a + 10`? Or does it have to emit a reload of `a` after the array access, in case `array[b]` was an OOB access that overwrote `a`?
The compiler's implementation defined behavior would simply be "if you tell me to write a value to an address, I'll create assembly that tries to write that value to that address". That's all. If this address is outside the allocated range of the array, there is no guarantee that it's safe that write this value, or that it won't break something else.
So in your example, no, the compiler is not required to reload 'a'. The compiler is allowed to presume that the array[x] syntax will have no affect on the value of a local variable, whether that variable is stored in a register or on the stack. The compiler is not guaranteeing safety, just best effort.