For a pointer p, could p < p+1 be false in an extreme case?

Is it possible, for a pointer variable p, that p<(p+1) is false? Please explain your answer. If yes, under which circumstances can this happen?

I was wondering whether p+1 could overflow and be equal to 0.

E.g. On a 64-bit PC with GCC-4.8 for a C-language program:

int main(void) {
   void *p=(void *)0xFFFFFFFFFFFFFFFF;

   printf("p      :%p\n", p);
   printf("p+1    :%p\n", p+1);
   printf("Result :%d\n", p<p+1);
}

It returns:

p      : 0xffffffffffffffff
p+1    : (nil)
Result : 0

So I believe it is possible for this case. For an invalid pointer location it can happen. This is the only solution I can think of. Are there others?

Note: No assumptions are made. Consider any compiler/platform/architecture/OS where there is a chance that this can happen or not.


Solution 1:

Is it possible, for a pointer variable p, that p<(p+1) is false?

If p points to a valid object (that is, one created according to the C++ object model) of the correct type, then no. p+1 will point to the memory location after that object, and will always compare greater than p.

Otherwise, the behaviour of both the arithmetic and the comparison are undefined, so the result could be true, false, or a suffusion of yellow.

If yes, under which circumstances can this happen?

It might, or might not, happen with

p = reinterpret_cast<char*>(numeric_limits<uintptr_t>::max);

If pointer arithmetic works like unsigned integer arithmetic, then this might cause a numeric overflow such that p+1 has the value zero, and compares less than p. Or it might do something else.

Solution 2:

What if I'm programming on DOS, and I have a far pointer (one composed of a segment and an offset), and it's pointing to the last address in the segment, and I add one to it, and the pointer wraps around? It looks like when you're comparing them, you normalize the pointers, so the second pointer p+1 would be less than p.

This is a stab in the dark though, I don't have a DOS C compiler handy to test on.

Solution 3:

Very simple: It cannot happen if there is no undefined behaviour involved. It can happen very easily in the presence of undefined behaviour. For details, read a copy of the C Standard or C++ Standard.

As a result, a conforming compiler is allowed to not evaluate the < operator at all and use 1 or true as the result instead. The same is true for arithmetic with signed integers (but not for unsigned integers, where it is possible for entirely legal code to have x > x+1).

Your example code isn't even C or C++, so you seem to have used the compiler in a mode where it isn't a standard conforming C or C++ compiler.

Solution 4:

It could happen with an invalid pointer.

But if the pointer points to a valid memory location, on many operating systems (e.g. Linux), it practically never happens (at least if the sizeof(*p) is not too big), because in practice the first and last pages of the address space are never mapped (but you could force a mapping with mmap & MAP_FIXED).

For freestanding implementations (i.e. inside a kernel, or on some microcontroller), things are different, and implementation specific (perhaps might be undefined behavior, or unspecified behavior).

Solution 5:

According to Pointer comparisons in C. Are they signed or unsigned? on Stack Overflow:

You can't legally compare arbitrary pointers in C/C++. The result of such comparison is not defined.