1) This result is unspecified.
2) This result is unspecified.*
3) Yes.
The relevant section in the standard is §5.9/2. Relational comparisons between the pointers p
and q
are only specified when:
p
and q
point to the same object or function, point to one past the end of the same array, or both are null. In this case, p <= q
and p >= q
are true, and p < q
and p > q
are false.
p
and q
point to nonstatic data members of the same object, the pointer to the later declared member compares greater. (Note, this comparison cannot be between access specifiers.)
p
and q
point to elements within the same array or one past the end of the array, the pointer to the element with the higher subscript or to one past the end of the array compares greater.
p
and q
point to data members of the same union object, in which case they compare equal.
In all other cases, the result is not specified.
*Because they are static, they (obviously) do not get the "nonstatic member" rules. They will be defined in some translation unit, and therefore are just like any other pointer. (Unspecified.)
Note! There is a way to get total ordering, and that is via std::less<void*>
(and all the other comparative function objects.)
This is in §20.3.3/8:
For templates greater
, less
, greater_equal
, and less_equal
, the specializations for any
pointer type yield a total order, even if the built-in operators <
, >
, <=
, >=
do not.
So while you don't know if std::less<void*>(&gFirst, &gSecond)
is true
or false
, you are guaranteed:
std::less<void*>(&gFirst, &gSecond) ==
std::greater<void*>(&gSecond, &gFirst);
std::less<void*>(&Data::First, &Data::Second) ==
std::greater<void*>(&Data::Second, &Data::First);
Which can prove useful.