This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-10-26


2528. Three-way comparison and the usual arithmetic conversions

Section: 7.4  [expr.arith.conv]     Status: C++23     Submitter: Cameron DaCamara     Date: 2022-01-26

[Accepted as a DR at the February, 2023 meeting.]

Consider an example like:

  void f(unsigned char i, unsigned ui) {
    i <=> ui;
  }

According to 7.6.8 [expr.spaceship] paragraph 4, the usual arithmetic conversions are applied to the operands. According to 7.4 [expr.arith.conv] bullet 1.5, the integral promotions are performed on both operands, resulting in i being converted from unsigned char to int. The operands are then of types int and unsigned int, so bullet 1.5.5 applies, further converting i to type unsigned int.

Unfortunately, that latter conversion, from int to unsigned int, is a narrowing conversion, which runs afoul of 7.6.8 [expr.spaceship] bullet 4.1, which prohibits narrowing conversions other than integral to floating in three-way comparisons.

Suggested resolution [SUPERSEDED]:

Change 7.4 [expr.arith.conv] bullet 1.5 as follows:

Otherwise, the integral promotions (7.3.7 [conv.prom]) shall be performed on both operands each operand shall be converted to a common type C. The integral promotion rules (7.3.7 [conv.prom] shall be used to determine a type T1 and type T2 for each operand.50 Then the following rules shall be applied to the promoted operands determine C:

Proposed resolution (approved by CWG 2023-02-09):

Change in 7.4 [expr.arith.conv] bullet 1.3 as follows, adding sub-bullets:

Otherwise, the integral promotions (7.3.7 [conv.prom]) are performed on both operands each operand is converted to a common type C. The integral promotion rules (7.3.7 [conv.prom]) are used to determine a type T1 and type T2 for each operand. [ Footnote: ... ] Then the following rules are applied to the promoted operands determine C: