C++ Logo

std-discussion

Advanced search

Re: Comparison operator rewriting, again

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Fri, 14 Jul 2023 10:59:29 -0400
On Fri, Jul 14, 2023 at 5:43 AM Andrey Semashev via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> On 7/14/23 04:31, Jason McKesson via Std-Discussion wrote:
> > 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.
>
> So are you saying non-const-qualified operator== is banned now? Seriously?

No, incoherent use of "non-const-qualified operator==" is "banned". If
you add a `const` qualifier to the `operator==` *or* remove the
`const` from the parameter, then it works.

Having `operator==` take one parameter as `const` and one as
non-`const` makes no sense. And I'll note that you don't defend this
as a legitimate piece of code, as code that makes logical sense. You
defend it on the basis that it "should" work.

> I'm sorry, but with all due respect, you're not the one to decide
> whether the code is "good" or "bad". Nor is anyone in the committee.

The first sentence is correct, but the last is categorically wrong.
That's *the job* of the C++ standards committee: to decide what is
valid and invalid C++.

>The
> code may need to discriminate const and non-const objects, or it may
> need to count operator== calls, or there may be any other reason for it
> to be not const-qualified.

None of those are *good* reasons. There is no reason for equality
testing to only have *one* of its operands be `const`. Both or
neither, but just one does not make sense. It violates the semantic
meaning of `==`.

And the whole point of the C++20 feature is to *promote* the semantic
meaning of `==`, to stop it from being just "a function that gets
called" and turn it into "equality testing".

> You don't know that, and the standard
> doesn't. It's not the standard's business to tell people what is "good"
> or "bad". It is to tell what is "valid" or "invalid". And I don't see
> the reason for this code to be invalid.

I've explained the reason. That you don't find it compelling is not
the point. You asked why this happens, and I've explained why.

Received on 2023-07-14 14:59:46