Title
Three-way comparison and the usual arithmetic conversions
Status
drafting
Section
7.4 [expr.arith.conv]
Submitter
Cameron DaCamara

Created on 2022-01-26.00:00:00 last changed 2 weeks ago

Messages

Date: 2022-02-18.07:47:23

Suggested resolution:

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:

  • If both operands have T1 and T2 are the same type, no further conversion is needed C shall be that type.

  • Otherwise, if both operands have T1 and T2 are both signed integer types or both have are unsigned integer types, the operand with the type of lesser integer conversion rank shall be converted to the type of the operand C shall be the type with greater rank.

  • Otherwise, if the operand that has the type U that is an unsigned integer type has rank greater than or equal to the rank of the other type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type, C shall be U.

  • Otherwise, if the type of the operand with S that is a signed integer type can represent all of the values of the other type of the operand with unsigned integer type, the operand with unsigned integer type shall be converted to the type of the operand with signed integer type, C shall be S.

  • Otherwise, both operands shall be converted to C shall be the unsigned integer type corresponding to the type of the operand with signed integer type.

Date: 2022-02-18.07:47:23

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.

History
Date User Action Args
2022-11-20 07:54:16adminsetstatus: open -> drafting
2022-02-18 07:47:23adminsetmessages: + msg6728
2022-01-26 00:00:00admincreate