Summary
Your program is not well-defined, even before getting to the dereference.
- You may increment
p
once, resulting in a one-past-the-end pointer.
- However, you may not decrement a one-past-the-end pointer.
Standardese
The rules in the standard relating to this capability are given in terms of arrays, but a note reminds us that a single object is considered to be an element of a single-element array for these purposes, citing the following passage which describes the meaning of your pointer:
[basic.compound/3]
: [..] A value of a pointer type that is a pointer to or past the end of an object represents the address of the first byte in memory ([intro.memory]) occupied by the object46 or the first byte in memory after the end of the storage occupied by the object, respectively. [..] For purposes of pointer arithmetic ([expr.add]) and comparison ([expr.rel], [expr.eq]), a pointer past the end of the last element of an array x
of n elements is considered to be equivalent to a pointer to a hypothetical array element n of x
and an object of type T
that is not an array element is considered to belong to an array with one element of type T
. [..]
So, yes, you can safely "get" the one-past-the-end pointer per these rules. Unfortunately, you can't do much with it afterwards, since the pointer addition and subtraction rules are defined thus:
[expr.add/4]
: When an expression J
that has integral type is added to or subtracted from an expression P
of pointer type, the result has the type of P
.
- If
P
evaluates to a null pointer value and J
evaluates to 0
, the result is a null pointer value.
- Otherwise, if
P
points to an array element i of an array object x
with n elements ([dcl.array]),80 the expressions P + J
and J + P
(where J
has the value j
) point to the (possibly-hypothetical) array element i+j of x
if 0≤i+j≤n and the expression P - J
points to the (possibly-hypothetical) array element i−j of x
if 0≤i−j≤n.
- Otherwise, the behavior is undefined.
…and &x+1
is not an element of even the made-up array presented by the object x
.
If it said "if P
points to a (possibly-hypothetical) array element i of an array object x
with n elements" then you'd be fine, because this would expand the behaviour given in the second bullet point to cover the one-past-the-end pointer (which is a "hypothetical array element of x
" per the first quote). But it doesn't, so we fall through to the third bullet point, leaving your program with undefined behaviour.