2

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...

2
  • 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.) Commented Oct 8, 2023 at 6:37
  • @user17732522 yes, sorry, I mean the latter, edited accordingly... Commented Oct 8, 2023 at 9:07

1 Answer 1

5

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. ...

Sign up to request clarification or add additional context in comments.

9 Comments

It is implementation-defined though whether NULL is a pointer type. It can be integral and then false is guaranteed. And in C++, as well as presumably C23, it may also fail to compile, if NULL is of type nullptr_t.
@user17732522 Mhm, but nobody's going to compare NULLs directly. OP most likely means that they have pointer variables they assign NULL to.
Yes, the question unfortunately is being imprecise about what it wants to ask.
@HolyBlackCat yes sorry, I edited the question accordingly, I mean variables assigned NULL to.
@0___________ No, implementation-defined means that the implementation should make a choice and document it (and there is only a limited set of permissible choice). The behavior of directly comparing NULL > NULL would, according to this answer, only be undefined if the implementation made the implementation-defined choice to use (void*)0 (or similar) as definition of NULL.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.