In said:
No, the standard does not resort to the notion of an object's
address space, but rather it guarantees what a s.c. program
can do (thus what a conforming implementation must support)
with regard to pointer arithmetic.
This notion is derived from from what the standard actually says.
The standard doesn't explicitly defines the notions of operator precedence
and associativity either, yet they can be derived from the actual text
of the standard (and even the standard itself uses them in examples and
footnotes).
It would be consistent
for an implementation to take advantage of the guarantees
when generating code to access a *declared* type, as
described earlier in this thread.
Only if the standard allowed that. Which it doesn't. 6.5.6p8 says:
"If the pointer operand points to an element of an array object" but it
doesn't require that array object to be declared as such. This is
precisely what makes pointer arithmetic work inside dynamically allocated
memory blocks. The standard doesn't have one rule for pointers
inside dynamically allocated memory and another for pointers inside
statically/automatically memory. This is why it is only the outermost
object that matters when deciding whether pointer arithmetic has a well
defined result or not. If this outermost object also satisfies the
definition of an array of type T, then it is this unnamed and undeclared
array that counts when pointer arithmetic is performed. Note that
footnote 88 (original C99 numbering) is consistent with this view.
The particular case when the aliasing array is of character type is even
*explicitly* mentioned in the standard:
pointer. When a pointer to an object is converted to a pointer
to a character type, the result points to the lowest addressed
byte of the object. Successive increments of the result, up to
the size of the object, yield pointers to the remaining bytes
of the object.
You can't really see this
for small examples, which is why I keep urging consideration
of the case when the subarray is nearly the size that can be
spanned by an offset field of a composite address.
It doesn't matter: the outermost object has created an address space that
is large enough for any subarray. There is no danger of pointer
arithmetic overflow as long as the result stays within the outermost
object.
Dan