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