This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 117a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-04-13
[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.50 Then the following rules shall be applied tothe promoted operands:
If
both operands havethe same type,no further conversion is needed.Otherwise, if
both operands havesigned integer types or bothhaveunsigned integer types,the operand with the type of lesser integer conversion rank shall be converted to the type of the operandwith greater rank.Otherwise, if the
operand that hasunsigned integer type has rank greater than or equal to the rank of the typeof the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.Otherwise, if the type
of the operand withsigned integer type can represent all of the values of the typeof 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.Otherwise,
both operands shall be converted tothe unsigned integer type corresponding to thetype of the operand withsigned integer type.
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. [ Footnote: ... ] Then the following rules are applied tothe promoted operands:
- If
both operands havethe same type,no further conversion is needed.- Otherwise, if both
operands havesigned integer types or bothhaveunsigned integer types,the operand with the type of lesser integer conversion rank is converted to the type of the operandwith greater rank.- Otherwise,
if the operand that hasunsigned integer type
- has rank greater than or equal to the rank of
the type of the other operand, the operand with signed integer type is converted to the type of the operand with unsigned integer type.- Otherwise, if
the type of the operand with signed integer typecan represent all of the values ofthe type of the operand with unsigned integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type.- Otherwise,
both operands are converted tothe unsigned integer type corresponding tothe type of the operand with signed integer type.