The reason is to keep the possibility to generate reasonable code. This applies to systems with a flat memory model as well as to systems with more complex memory models. If you forbid the (not very useful) corner cases like adding or subtracting out of arrays and demanding a total order on pointers between objects you can skip a lot of overhead in the generated code.
The limitations imposed by the standard allows the compiler to make assumptions on pointer arithmetic and use this to improve quality of the code. It covers both computing things statically in the compiler instead of at runtime and choosing which instrutions and addressing modes to use. As an example, consider a program with two pointers p1
and p2
. If the compiler can derive that they point to different data objects it can safely assume that any no operation based on following p1
will ever affect the object pointed to by p2
. This allows the compiler to reorder loads and stores based on p1
without consider loads and stores based on p2
and the other way around.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…