Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions.
Usual arithmetic conversions are defined as follows:
Stage 1
| (since C++11) |
| (since C++23) |
Both operands are converted to a common type C. Given the types T1 and T2 as the promoted type (under the rules of integral promotions) of the operands, the following rules are applied to determine C:
T1 and T2 are the same type, C is that type. T1 and T2 are both signed integer types or both unsigned integer types, C is the type of greater integer conversion rank. T1 and T2 is an signed integer type S, the other type is an unsigned integer type U. Apply the follwing rules: U is greater than or equal to the integer conversion rank of S, C is U. S can represent all of the values of U, C is S. C is the unsigned integer type corresponding to S. | If one operand is of enumeration type and the other operand is of a different enumeration type or a floating-point type, this behavior is deprecated. | (since C++20) |
Every integer type has an integer conversion rank defined as follows:
| (since C++11) |
| (since C++11) |
char8_t (since C++20), char16_t, char32_t, (since C++11) and wchar_t) equal the ranks of their underlying types, which means:
| (since C++20) |
| (since C++11) |
| (since C++11) |
T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3. The integer conversion rank is also used in the definition of integral promotion.
Every floating-point type has a floating-point conversion rank defined as follows:
| (since C++23) |
Floating-point conversion subrankFloating-point types that have equal floating-point conversion ranks are ordered by floating-point conversion subrank. The subrank forms a total order among types with equal ranks. The types | (since C++23) |
The floating-point conversion rank and subrank are also used to.
| (since C++23) |
std::complex's converting constructor is explicit, or The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| CWG 2528 | C++20 | the three-way comparison between unsigned char and unsigned int is ill-formed because of the intermediate integral promotion[1] | determines the common type based on the promoted types, without actually promoting the operands[2] |
unsigned char is promoted to int at the beginning of stage 3, then it is converted to unsigned int. However, the latter conversion is narrowing, which makes the three-way comparison ill-formed. unsigned int. The difference is that unsigned char is directly converted to unsigned int without the intermediate integral promotion. The conversion is not narrowing and hence the three-way comparison is well-formed.
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/usual_arithmetic_conversions