Compilation error with C++20 standard: unable to rewrite operator!= because operator== does not return a bool

Description

Hello,

In C++20, secondary comparaison operators are possibly rewritten from their primary operators. This, generally, is not a concern as far as the operator== retturns a boolean. This is not the case as the UBool is an integer. As a matter of fact, the compiler is not able to rewrite the operator!=. We have to help it a little: I will give a PR soon.

To reproduce:

Regards,
Stac

Activity

Show:
Laurent Stacul
February 14, 2020, 2:49 PM

Actually, there are some changes I did not put in the PR because as you say it seems that there are still some bugs in gcc 10 support of C++20. I keep them on my side while I am waiting an answer to this ticket I opened while investigating the compilation issues with ICU: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93699.

So maybe some changes, especially in the base class are not needed. I will try to improve my PR to have a minimal changes set when I have the confirmation it is (or not) a bug.

Markus Scherer
February 18, 2020, 7:41 PM

Not finding that the subclass inherits operator!= from the base class has got to be a compiler bug.

Vemund Handeland
August 6, 2020, 6:15 PM

The rules have changed for comparison operators with C++20. E.g.: the compiler will synthesize operator!= if you have operator== and it will also synthesize candidates with the arguments reversed.
It does not look like GCC will accept the bug. My first suggestion would be to change the return type of all comparison operators to bool.

Vemund Handeland
August 6, 2020, 6:20 PM

But changing return type to bool is not enough to fix all comparison operator issues. Using TimeUnitFormat as an example. Extracted and simplified the problematic operators.

See https://godbolt.org/z/f4Y4eE

Clang 10 and GCC 10 rejects the code in C++20 mode
Both compilers accept the code after deleting TimeUnitFormat::operator!=
It is kind of redundant but saves a virtual call in preC++20 mode. Clang still gives a warning about ambiguity.

In this case I would delete TimeUnitFormat::operator!= and instead provide MeasureFormat::operator==(const MeasureFormat&) and MeasureFormat::operator!=(const MeasureFormat&). Still saving a virtual call in pre-C++20 and no ambiguity warning + potential error in current and future compilers in C++20 mode

TimeUnitFormat is deprecated but other Format types have similar issues.

Markus Scherer
September 16, 2020, 8:43 PM

Fredrik reviewed the standard changes, and we discussed this today in the team meeting. In fact the C++ standard has deliberately changed and breaks existing code, and the cleaner solution will require long-lived conditional code à la #if C++20 or later.

We could add lots of additional operators returning UBool, but we decided it’s cleaner and simpler to change operator== to return bool and conditionally (if C++20 or higher, rather than earlier versions) remove operator!=. Other API will continue to use UBool.

Fredrik, please add more details about the problem and the two options, as discussed.

Assignee

Fredrik Roubert

Reporter

Laurent Stacul

Components

Labels

None

Reviewer

None

Priority

assess

Time Needed

Hours

Fix versions

Configure