The
usual arithmetic conversions are performed for operands of arithmetic or
enumeration type.

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.

For subtraction, one of the following shall hold:

- both operands have arithmetic or unscoped enumeration type; or
- both operands are pointers to cv-qualified or cv-unqualified versions of the same completely-defined object type; or
- the left operand is a pointer to a completely-defined object type and the right operand has integral or unscoped enumeration type.

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.

- Otherwise, if P points to an array element i of an array object x with n elements ([dcl.array]),68 the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) array element of x if and the expression P - J points to the (possibly-hypothetical) array element of x if .
- Otherwise, the behavior is undefined.

When two pointer expressions P and Q 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.layout]).

- Otherwise, if P and Q point to, respectively, array elements i and j of the same array object x, the expression P - Q has the value .

For addition or subtraction, if the expressions P or Q have
type “pointer to cv T”, where T and the array element type
are not similar, the behavior is undefined.

[*Example 1*: int arr[5] = {1, 2, 3, 4, 5};
unsigned int *p = reinterpret_cast<unsigned int*>(arr + 1);
unsigned int k = *p; // OK, value of k is 2 ([conv.lval])
unsigned int *q = p + 1; // undefined behavior: p points to an int, not an unsigned int object
— *end example*]

68)68)

As specified in [basic.compound],
an object that is not an array element
is considered to belong to a single-element array for this purpose and
a pointer past the last element of an array of n elements
is considered to be equivalent to a pointer to a hypothetical array element
n for this purpose.