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:
Markus Scherer
February 23, 2021, 8:59 PM

Hi Fredrik, given that it’s 2021 I assume that people will want to start using C++20 sometime soon, so I bumped up the priority here. Looking back, we will need API changes, and those are too late for ICU 69.

Please do add more details as discussed in September (see above) and prepare a proposal for ICU 70.

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.

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.

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.

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.

Assignee

Fredrik Roubert

Reporter

Laurent Stacul

Components

Labels

None

Reviewer

None

Priority

major

Time Needed

Hours

Fix versions