C++ Logo

std-discussion

Advanced search

Re: Comparison operator rewriting, again

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Thu, 13 Jul 2023 21:31:25 -0400
On Thu, Jul 13, 2023 at 7:49 PM Andrey Semashev via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> 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.)
>
> Could someone explain the rationale behind making this code invalid in
> C++20? Is there a rationale at all?

Your entire point is premised on the idea that this code was good
because it worked. That the code was "innocent".

But it wasn't. It was something you could get away with, but it was
ultimately not good code. Besides the fact that you could technically
call the function, what is the rationale that says that this code was
*sensible* even when it worked?

Unless you are doing something special with `operator==`, there is no
reason for it not to be `const`. In fact, your function even takes a
proper `const&` of the other item. But how does that make sense? How
can a symmetric `==` be a `const` operation on one of its items but
not on the other?

What does it mean that `this` is not `const`?

If you made it a proper `const` function, not only would the error go
away, you would have *better code*. Code that more accurately
describes what it is doing.

While there are some cases of legitimately reasonable code that
operator rewriting broke, this is not one of them. This is a trivially
fixable problem where the original code was already dubious even if
the compiler was silent about it.

Received on 2023-07-14 01:31:42