C++ Logo

std-discussion

Advanced search

Re: Pointer comparison with operators vs function objects

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Mon, 15 Sep 2025 18:12:58 +0100
On 15 September 2025 14:48:01 BST, David Brown via Std-Discussion <std-discussion_at_[hidden]> wrote:
>On 15/09/2025 14:48, Yongwei Wu via Std-Discussion wrote:
>> As per my understanding of the C++ standard, operators like < should not be used to compare unrelated pointers, but function objects like std::less can. Is there any reason why we cannot make p1 < p2 just behave like std::less<T*>{}(p1, p2)? I really cannot think any.
>>
>> Any insights on this?
>>
>
>First ask yourself, is there any reason why you would want to compare unrelated pointers for ordering? If there are no real-world use-cases that can't be handled well enough using the existing C++ language, then there is no reason to change.
>
>Such comparisons can be helpful for implementations of standard functions like memmove(). But those are part of the implementation - a standard library implementation can use compiler-specific features or implementation-specific knowledge to implement its functions efficiently, relying on features that are not part of the C++ standards.
>
>There might be occasions when user-written code can have an interest in orderings of pointers, such as for writing specialised memory management routines or perhaps holding unrelated pointers in a searchable data structure. I would expect that for those situations, you can simple cast to uintptr_t and compare those without any overhead. (Use the casts just for the comparisons - avoid casting back and forth between uintptr_t and pointer types because the compiler might lose useful information.)

You can't portably use uintptr_t to compare pointers in a way that is consistent with language's pointer comparison, this is not guaranteed by the language.

> You will probably find that this is what is being the std::less implementation in many C++ libraries.
>
>
>As for why comparing unrelated pointers (except for equality) is UB, this might be because C and C++ can work on systems with complicated address spaces. Modern x86, ARM, and other common "big" processors have nice, simple flat address spaces. But some other targets have complicated address spaces - the same underlying representation in a pointer might refer to different physical addresses depending on its type or how the pointer is used. (An example of a currently available processor with multiple address spaces and with C++ support is the AVR microcontroller family.) On many such systems, it would be possible to define a comparison relationship - but why bother, if the results don't actually mean anything?
>
>

Received on 2025-09-15 17:13:06