C++ Logo

std-discussion

Advanced search

Re: Comparison operator rewriting, again

From: Daniel Krügler <daniel.kruegler_at_[hidden]>
Date: Fri, 14 Jul 2023 12:21:30 +0200
Am Fr., 14. Juli 2023 um 01:49 Uhr schrieb Andrey Semashev via
Std-Discussion <std-discussion_at_[hidden]>:
>
> Hi.
>
> Recently I got bitten by this innocent piece of code:
>
> struct comparible_UDT
> {
> int i_;
> comparible_UDT() : i_(2){}
> bool operator == (const comparible_UDT& v) { return v.i_ == i_; }
> };
>
> bool test(comparible_UDT left, comparible_UDT right)
> {
> return left == right;
> }
>
> This used to work fine until C++20, where the completely broken piece
> of... core language called operator rewriting appeared. Now gcc and
> clang mercifully accept this code, albeit with a warning, and MSVC fails
> to compile it saying the operator== is ambiguous with its rewritten
> self. Which, of course, I did not write and cannot suppress.
>
> https://godbolt.org/z/hsfE8sYfG
>
> (Yes, I know I can fix this by marking the operator== as const, that's
> not the point. The point is that the code above should work as written,
> there's nothing ambiguous about it.)

Alternatively you could define

bool operator!=(const comparible_UDT& v);

if the non-const operator== was by design.

And if you think that user code should not attempt to call operator!=
for some reason, you could change the definition to

bool operator != (const comparible_UDT& v) = delete;

> Could someone explain the rationale behind making this code invalid in
> C++20? Is there a rationale at all?

It is documented as breaking change in Annex C, [diff.cpp17.over].

> If there isn't, is this a bug? Should it be reported as a DR?

This kind of problem was foreseen but was still accepted. I think it
wont be accepted as an issue, unless you provide additional
information why this is a non acceptable change.

I can understand that this is unfortunate, but almost unpreventable
when the language is willing to make progress with acceptable costs.
Just as a complete different example: You would have had a similar
breaking change if your pre-C++20 code did have a variable named as
"consteval", for example, which was then introduced as keyword.

Thanks,

- Daniel

Received on 2023-07-14 10:21:43