For addition, either both operands shall have arithmetic or unscoped enumeration
type, or one operand shall be a pointer to a completely-defined object
type and the other shall have integral or unscoped enumeration type.
When an expression that has integral type is added to or subtracted from
a pointer, the result has the type of the pointer operand.
If the expression P points to element x[i]
of an array object x with n elements,86
the expressions P + J and J + P
(where J has the value j)
point to the (possibly-hypothetical) element
x[i+j] if 0≤i+j≤n;
otherwise, the behavior is undefined.
Likewise, the expression P - J
points to the (possibly-hypothetical) element
x[i−j] if 0≤i−j≤n;
otherwise, the behavior is undefined.
When two pointers to elements of the same array object are subtracted,
the type of the result is an implementation-defined signed
integral type; this type shall be the same type that is defined as
std::ptrdiff_t in the <cstddef>
header ([support.types]).
If the expressions P and Q
point to, respectively,
elements
x[i]
and
x[j]
of the same array object x,
the expression P - Q has the value i−j;
otherwise, the behavior is undefined.
For addition or subtraction, if the expressions P or Q have
type “pointer to cvT”, where T and the array element type
are not similar, the behavior is undefined.
An object that is not an array element is considered to belong to a
single-element array for this purpose; see [expr.unary.op].
A pointer past the last element of an array x of n elements
is considered to be equivalent to a pointer to a hypothetical element
x[n] for this purpose; see [basic.compound].