The usual arithmetic conversions are performed on operands of arithmetic
or enumeration type.
If both operands are pointers, pointer
conversions ([conv.ptr]) and qualification conversions ([conv.qual])
are performed to bring
them to their composite pointer type (Clause [expr]).
After conversions, the operands shall have the same type.
If two pointers point to different elements of the same array, or to
subobjects thereof, the pointer to the element with the higher subscript
compares greater.
If two pointers point to different non-static data members of the same
object, or to subobjects of such members, recursively,
the pointer to the later declared member compares greater provided the
two members
have the same access control (Clause [class.access])
and provided their class is not a union.
If both operands (after conversions) are of arithmetic or enumeration type, each
of the operators shall yield true if the specified relationship is true
and false if it is false.
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].