If I have two pointer variables, a and b, what does it mean to to use the statement "a < b"? Is doing so supposed to compare the values of their memory addresses? If so, what would be the order of memory addresses in the computer?
-
1I suspect that something like this will be very language specific. In some naive cases pointers are literally (or can be treated like) memory location. In other cases they are a very specific type, and operators will have type specific behaviour. – Nov 10 '17 at 19:04
-
Related [Given that p is a pointer is “p > nullptr” well-formed?](https://stackoverflow.com/q/26590267/1708801) – Shafik Yaghmour Nov 10 '17 at 20:45
-
My answer to [Rationale for pointer comparisons outside an array to be UB](https://stackoverflow.com/a/31151779/1708801) is also related. – Shafik Yaghmour Nov 10 '17 at 20:46
1 Answers
In C and C++, comparing pointers using relational operators is allowed in the case where you have two pointers into the same array and want to see their relative ordering (there's an exception to this rule that I'll mention in a little bit). For example, imagine that p
and q
each point somewhere into the middle of array arr
, as shown here:
int arr[9];
int* p = &arr[1];
int* q = &arr[4];
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
arr | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
| |
p q
In this case, the expression p < q
asks "is the index in the array that p
points at lower than the index in the array that q
points at?" In the above context, the answer is "yes." If p
and q
were reversed, or if they pointed at the exact same element, the answer would be "no."
The language standards in C and C++ both say that the result of comparing pointers that don't point into the same array is unspecified, which intuitively makes sense because unrelated objects might be scattered around pretty much randomly in memory, or be related in a way that's implementation-dependent (does your stack grow up or down?)
The one exception to this is that you're allowed to compare a pointer one object past the end of an array to a pointer in the array. For example, take a look at this setup:
int arr[9];
int* p = &arr[1];
int* q = &arr[9];
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
arr | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
| |
p q
Here, q doesn't point into the array arr
. However, the language spec allows you to safely compare p and q. This is why, for example, you can safely use this iterator-style loop in C++:
for (int* itr = arr; itr != arr + /* arr's size */; itr++) {
...
}

- 362,284
- 104
- 897
- 1,065
-
1To add: "... in the case where you have two pointers into the same array _or object_". This array discussion also applies to a single object as if it was an array of one. `some_type x;` `&x+1 > &x` is well defined. §6.5.8 4 – chux - Reinstate Monica Nov 10 '17 at 20:28
-
1You can also compare pointers to members of the same aggregate object, e.g., a pointer to the `int a` in a struct object with a pointer to the `double b` in the same object. – Eric Postpischil Nov 10 '17 at 22:22
-
@EricPostpischil I didn't know you could do that. I assume you need to use some flavor of `char *` pointers across objects of different types to avoid strict aliasing violations? – templatetypedef Nov 10 '17 at 22:31
-
@templatetypedef: I was wrong about being able to compare disparate members of an object. You can compare members of an object, but they must have compatible types. Then the standard says “If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure, and pointers to array elements with larger subscript values compare greater than pointers to elements of the same array with lower subscript values. All pointers to members of the same union object compare equal.” – Eric Postpischil Nov 11 '17 at 00:37
-
@templatetypedef: I cannot say I have ever seen it used. It’s a bit weird; you would have to have two pointers that you know point into the same struct, but you do not know where in the struct they point. Did you forget? Why do you even care? I suppose there is a case where you have some link structure where sometimes you point to one member of the struct (e.g., a “forward” link in a chain) and sometimes you point to another (e.g., a “reverse” link), and comparing would let you figure out which of those a particular pointer points to. – Eric Postpischil Nov 11 '17 at 00:40