C++ Logo

std-discussion

Advanced search

Re: Pointer comparison with operators vs function objects

From: Nate Eldredge <nate_at_[hidden]>
Date: Tue, 16 Sep 2025 05:32:21 +0000
I realized I mixed up who I was replying to; sorry about that. Everywhere below that I said "your proposal" I meant "Yongwei Wu's proposal", which as I understood it, was to make `<` on pointers match the semantics of `std::less`: a strict total ordering over all pointers, not just those pointing within the same array. And I understood that this was to apply to data pointers as well as function pointers. The points I made were in reference to data pointers, and it sounds like we both agree there.

If there is a proposal is to make `<` match std::less on *function* pointers only, while keeping its existing semantics on *data* pointers, then indeed I don't see any particular difficulties with that, except that the inconsistency between the two might be counterintuitive.

> On Sep 15, 2025, at 23:10, Thiago Macieira <thiago_at_[hidden]> wrote:
>
> On Monday, 15 September 2025 20:53:25 Pacific Daylight Time Nate Eldredge
> wrote:
>> Sure, but since you can't have an array of functions, comparing function
>> pointers falls outside the common case of "comparing pointers within the
>> same array" that the < operator is meant for. Here, I agree, you have to
>> pay the runtime cost of std::less regardless, and all that your proposal
>> changes is the syntax.
>
> I agree, but I come to the opposite conclusion: because operator< is only
> defined for items in an array, defining it for functions would imply it needs to
> take the full memory space regardless, so on 16-bit DOS it would need to do
> 32-bit comparisons for __far function pointers, when it doesn't need to do so
> for __far data pointers.
>
>>> Besides, std::less<T __far *> can be different from std::less<T __near *>.
>>
>> Yes, of course they would be different. But that's beside my point.
>
> I don't think so.
>
> [snip]
>> In this code model, any two pointers within the same array (or class object)
>> must have the same segment part, and the < operator is only specified for
>> comparisons of such pointers; so the compiler may *assume* the segments are
>> equal, and compare the offsets only. (Likewise in this code model, `p++`
>> increments the offset only, and doesn't touch the segment.) So as it
>> stands, the test `p < endp` consists of one cheap `cmp` instruction.
>
> I agree.
>
> However, we're talking about functions objects.
>
>> But under your proposal, the compiler would be required to emit code for `p
>> < endp` that would have well-specified behavior even if `p` and `endp` do
>> not point into the same array. That means it does have to compare the
>> segment as well as the offset parts, which at least doubles the runtime
>> cost - and much more if we have to handle overlapping segments by computing
>> linear addresses (I'm not sure if x86-16 ABIs allowed that).
>
> No, I don't see how that logically follows from what I said. There's no need
> for that. I am still agreeing with you that a __far data pointer need only
> compare the offset part for ordering.
>
>> In this example, a smart compiler (which typical x86-16 compilers were not)
>> could hoist the segment part of the comparison out of the loop, but we
>> could certainly construct an example where this would not be possible.
>> (And I realize this example has UB if `endp` has a higher address than all
>> of `arr`; but greater than all its elements; we could assume the calling
>> code avoids that case, or modify this function to handle it.)
>>
>> All that said, you certainly could make an argument that the benefits of the
>> proposal outweigh the costs, but IMHO you'd need data to quantify them.
>> The costs do exist.
>
> I don't see how any of this has anything to do with the original proposal,
> which was about function objects.
>
> Functions don't exist in arrays, so if they are orderable, the limitation that
> their segment portion be the same wouldn't apply. The ordering would need to
> be 32-bit, which would be the exact same cost for std::less<void __far *>.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Principal Engineer - Intel Platform & System Engineering

Received on 2025-09-16 05:32:25