Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #82707

Re: A counterintuitive breaking change related to new comparisons

From Andrey Tarasevich <andreytarasevich@hotmail.com>
Newsgroups comp.lang.c++
Subject Re: A counterintuitive breaking change related to new comparisons
Date 2022-01-03 14:13 -0800
Organization A noiseless patient Spider
Message-ID <sqvsdu$trp$1@dont-email.me> (permalink)
References <sqvcts$h94$1@dont-email.me> <20220103210610.ec3859f4d0b23edfc9d217c3@cvine--nospam--.freeserve.co.uk>

Show all headers | View raw


On 1/3/2022 1:06 PM, Chris Vine wrote:
>> A colleague discovered that switching from `-stc=c++17` to `-std=c++20`
>> in their project resulted in a different behavior from some associative
>> containers. A bit of research allowed to narrow down the culprit to what
>> can be demonstrated by the following minimalist example
>>
>>     #include <iostream>
>>
>>     struct S
>>     {
>>       char c;
>>
>>       operator const char *() const { return &c; }
>>
>>       friend bool operator <(const S& lhs, const S& rhs)
>>         { return lhs.c < rhs.c; }
>>     };
>>
>>     int main()
>>     {
>>       std::pair<int, S> p1{}, p2{};
>>       std::cout << (p1 < p2) << (p2 < p1) << std::endl;
>>     }
>>
>> C++17 compilers output `00`. C++20 compilers output `01` (or, perhaps,
>> `10`).
>>
>> The obvious guess is that comparisons for `std::pair` work differently
>> in C++20 after the introduction of `<=>`. And indeed, the `<=>` operator
>> for `std::pair` in this case ignores the user-defined `<` and instead
>> opts for raw pointer comparison through conversion to `const char *`.
>> This is a rather surprising and counterintuitive breaking change, to put
>> it mildly...
>>
>> If we remove the user-defined conversion to `const char *`, C++20 will
>> use the user-defined `<` and also output `00`.
>>
>> The above results were obtained with GCC. Clang 10 outputs `00` even in
>> `-std=c++20` mode, but Clang 11 and later output `01`.
> 
> As p1 and p2 are not within the same array or object, I believe
> operator< has undefined behaviour so the compiler is within its rights
> to behave this way (that was certainly the case in C++11).  If you use
> std::less it should work, as it provides an implementation defined
> total order over pointers even where operator< does not.

Um... The top-level `<` operation in `p1 < p2` is a user-defined 
operator. It is not subject to any restrictions, like "within the same 
array or object" or somesuch.

On the other hand, comparison between two `const char *` pointers, 
obtained from `p1` and `p2` probably does have undefined behavior. 
However, that's completely besides the point. The point is that in C++20 
mode the compiler even opted to perform implicit conversion to `const 
char *`. That is already surprising.

Before C++20 the conversion to `const char *` is not used and everything 
is perfectly defined here. There's no "undefined behavior" of any kind 
in C++17 semantics of this code.

-- 
Best regards,
Andrey Tarasevich

Back to comp.lang.c++ | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

A counterintuitive breaking change related to new comparisons Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-03 09:48 -0800
  Re: A counterintuitive breaking change related to new comparisons Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2022-01-03 21:06 +0000
    Re: A counterintuitive breaking change related to new comparisons Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-03 14:13 -0800
      Re: A counterintuitive breaking change related to new comparisons Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2022-01-04 00:23 +0000
        Re: A counterintuitive breaking change related to new comparisons Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-03 16:33 -0800
          Re: A counterintuitive breaking change related to new comparisons Juha Nieminen <nospam@thanks.invalid> - 2022-01-04 08:27 +0000
            Re: A counterintuitive breaking change related to new comparisons "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-01-04 17:24 +0100
            Re: A counterintuitive breaking change related to new comparisons Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-04 10:26 -0800
        Re: A counterintuitive breaking change related to new comparisons Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2022-01-04 00:39 +0000
  Re: A counterintuitive breaking change related to new comparisons Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-03 14:24 -0800
    Re: A counterintuitive breaking change related to new comparisons "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-01-03 23:55 +0100
    Re: A counterintuitive breaking change related to new comparisons Manfred <noname@add.invalid> - 2022-01-04 00:56 +0100
      Re: A counterintuitive breaking change related to new comparisons Manfred <noname@add.invalid> - 2022-01-04 00:59 +0100
      Re: A counterintuitive breaking change related to new comparisons Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-03 16:59 -0800
        Re: A counterintuitive breaking change related to new comparisons Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2022-01-04 01:27 +0000
        Re: A counterintuitive breaking change related to new comparisons Öö Tiib <ootiib@hot.ee> - 2022-01-04 14:49 -0800
          Re: A counterintuitive breaking change related to new comparisons Öö Tiib <ootiib@hot.ee> - 2022-01-04 15:16 -0800
          Re: A counterintuitive breaking change related to new comparisons Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-05 09:06 -0800
  Re: A counterintuitive breaking change related to new comparisons "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-01-03 18:51 -0800
  Re: A counterintuitive breaking change related to new comparisons wij <wyniijj@gmail.com> - 2022-01-04 03:53 -0800
    Re: A counterintuitive breaking change related to new comparisons wij <wyniijj@gmail.com> - 2022-01-04 21:59 -0800

csiph-web