C: NULL > NULL always false?

Is it guaranteed by the C standard that, given type_t* x = NULL; type_t* y = NULL; we always have x > y evaluating as false? I ask because of the conversation in initial or terminal malloc buffer possible? from which it seems that one should be careful with pointer comparison, and only compare when one is dealing with pointers to elements of the same array, loosely speaking. However, it is convenient to have x > y evaluating as false guaranteed, because I want a struct which is an stack-ish array having fields for the first and post-last elements, and if this array still has 0 elements, it is convenient to set these fields to be NULL, and it is convenient to still allow for for looping over elements of the array, without checking explicitly whether the array has 0 elements or more, so such a comparison is handy…

  • You should consider whether you really want to ask whether or not NULL > NULL as an expression is guaranteed to evaluate to false or whether you want to ask whether X > Y where both X and Y are null pointer values (of the same type) is guaranteed to evaluate to false. These are quite different questions. (In particular, NULL is not a null pointer value in general, but a null pointer constant instead.)

    – 




  • @user17732522 yes, sorry, I mean the latter, edited accordingly…

    – 




Surprisingly, in C it appears to cause undefined behavior. Only == and != can work with null pointers. The workaround is to cast the pointers to uintptr_t and compare the results.

C17 6.5.8 Relational operators /5

When two pointers are compared, the result depends on the relative locations in the address space
of the objects pointed to. If two pointers to object types both point to the same object, or both point
one past the last element of the same array object, they compare equal. 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. If the expression
P points to an element of an array object and the expression Q points to the last element of the same
array object, the pointer expression Q+1 compares greater than P. In all other cases, the behavior is
undefined.

(bold mine)

This is unlike C++, where there’s a clause explicitly saying that <,<=,>,>= are consistent with ==,!=:

[expr#rel]/5

If two operands p and q compare equal ([expr.eq]), p<=q and p>=q both yield true and p<q and p>q both yield false. …

Leave a Comment