According to the C++23 standard, what is the output of this program?
#include <iostream>
int main() {
unsigned short zero = 0, one = 1;
if (zero - one < zero)
std::cout << "less";
else
std::cout << "more";
}Integral promotion is applied to the operands. The sizes of the integral types are implementation defined.
The program is unspecified / implementation defined
Since unsigned underflow is defined to wrap around, we might expect that zero - one would always be a large positive value (the maximum representable value of unsigned short). But in fact, this only happens when short and int have the same size! In the more common case where short is smaller than int, because short has a conversion rank smaller than int, the operands are promoted to int before applying the operation.
This is because whenever arithmetic operations like addition are performed, the usual arithmetic conversions (§[expr.arith.conv]¶1.3) are applied (§[expr.add]). The usual arithmetic conversion promotes integral types of conversion rank lower than int to int if int can represent all the values of the source type, and otherwise to unsigned int. (§[conv.prom]¶1).
unsigned short has conversion rank lower than int (§[conv.rank]¶1) and so gets converted to int if int can also represent all values representable in unsigned short, which is true when the unsigned short is smaller. In this case, the result of the operation is -1 with type int, and less is printed.
If short and int have the same size, unsigned short instead gets converted to an unsigned int, the result wraps around to a large value, and more is printed.