It is not allowed to dereference such a pointer, even if it compares equal to another valid pointer.
Section 6.5.6p8 regarding the +
operator states:
When an expression that has integer type is added to or
subtracted from a pointer, the result has the type of the pointer
operand. If the pointer operand points to an element of an array
object, and the array is large enough, the result points to an element
offset from the original element such that the difference of the
subscripts of the resulting and original array elements equals the
integer expression. In other words, if the expression P
points to
the i-th element of an array object, the expressions (P)+N
(equivalently, N+(P)
) and (P)-N
(where N
has the value n)
point to, respectively, the i+n-th and i−n-th elements of the
array object, provided they exist. Moreover, if the
expression P
points to the last element of an array object, the
expression (P)+1
points one past the last element of the array
object, and if the expression Q
points one past the last
element of an array object,the expression (Q)-1
points to the
last element of the array object. If both the pointer operand
and the result point to elements of the same array object,
or one past the last element of the array object, the evaluation
shall not produce an overflow; otherwise, the behavior is undefined.
If the result points one past the last element of the array object, it shall not be used as the operand of a unary *
operator that is
evaluated
On a related note, some compilers have the concept of pointer provenance, meaning it internally keeps track of the source of a pointer. A consequence of this is that if two unrelated variables are adjacent in memory, comparing the address of one to one-past the address of the other will always evaluate to false, even if the addresses are the same.