C++ Logo

sg12

Advanced search

Re: [ub] Justification for < not being a total order on pointers?

From: Christopher Jefferson <chris_at_[hidden]>
Date: Wed, 16 Oct 2013 22:51:15 +0100
On 16 October 2013 22:43, Nevin Liber <nevin_at_[hidden]> wrote:
> On 16 October 2013 16:23, Christopher Jefferson <chris_at_[hidden]>
> wrote:
>>
>> On 16 October 2013 16:06, Gabriel Dos Reis <gdr_at_[hidden]> wrote:
>>
>> > |
>> > | So what about std::less<void>? Should people be using it?
>> >
>> > What is wrong about it?
>> >
>>
>> Just to clarify this problem (because I don't think anyone has
>> described the problem in detail).
>>
>> Given two int* pointers x,y;
>>
>> std::less<int*>()(x,y) is defined and a total ordering.
>>
>> std::less<>()(x,y) invokes undefined behaviour, as it is defined as
>> calling 'x<y'.
>
>
> It does not invoke ub, as there are weasel words forcing this to work
> correctly for pointers.

Oh, I did not realise that. I assume those weasel words are:

20.10.5: 14 For templates greater, less, greater_equal, and
less_equal, the specializations for any pointer type yield a total
order, even if the built-in operators <, >, <=, >= do not.

I did not think that applied for the std::less<void> specialisation,
but I can imagine how you could read that it did.

>>
>>
>> Therefore std::less<> is not a drop in replacement for std::less<int*>.
>
>
> std::less<> can be a drop in replacement for std::less<int*>.
>
> In general though, std::less<>::operator()(T const&, T const&) is not a drop
> in replacement for std::less<T>::operator()(T const&, T const&), even though
> it is intended to be. This is problematic.

Yes, I agree.

>
>>
>> This is also hard to fix, as std::less<> can take different types, so
>> it can't just always delegate to std::less<T> for the actual type T
>> being compared.
>
>
> Well, it could for the case I wrote above, but that would be more than an
> editorial change to C++14, and definitely a breaking change after C++14
> ships.
>
>>
>> I was under the impression this problem was generally known, but had
>> been ignored for some reason I did not know, as I do not attend
>> meetings.
>
>
> I don't remember it coming up in Bristol when we discussed it. It isn't the
> only place in the standard library that uses operator< instead of std::less;
> I'd rather see that addressed in one go.
>
> I certainly have no plans to bring up any issues with less<>.
>
> Then again, my advice to developers is to forget about less<T> (that route
> lies madness) and just write an operator< for their class so they'll never
> see the problem. However, this advice differs from the advice of Gaby and
> Sean.

This is also the advice I teach.

Chris

Received on 2013-10-16 23:51:16