... the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
- If both operands have the same type, then no further conversion is needed.
- Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
- Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then 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 type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
- Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type
Can someone explain me the difference between the last and penultimate points from above? Why is the last one needed? Aren't all the cases covered by the first 4? If someone can give an example would be perfect. Thanks
CodePudding user response:
Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type
Let's consider a system where sizeof( long )
is equal to sizeof( unsigned int )
(for example the both are equal to 4
).
In this case though the rank of the type long
is greater than the rank pf the type unsigned int
nevertheless an operand of the signed type long
is unable to represent all values of the type unsigned int
.
In this case the both operands used in a binary operation are converted to the type unsigned long
.
Or another example when in some systems sizeof( long long )
is equal to sizeof( unsigned long )
and equal to 8
. In this case again the both operands of these types will be converted to the type unsigned long long
because the rank of long long
is greater than the rank of the type unsigned long
but not all values of operand of the type unsigned long
can be represented by an object of the signed type long long
.
That is this quote describes the situation when the rank pf an operand of a signed integer type is greater than the rank of an unsigned integer type but the operand of the signed integer type is unable to represent all values of the operand of the unsigned integer type.
The preceding quote
Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
describes the situation when the rank of a signed integer type is greater than the rank of an unsigned integer type and operand of the signed integer type can represent all values of operand of the unsigned integer type. For example when one operand of the type long
and other of the type unsigned int
and sizeof( long )
is equal to 8
and sizeof( unsigned int )
is equal tp 4
.
CodePudding user response:
We reach (4) when one has a signed type and one has an unsigned type, and the signed type has a greater rank.
For example, this could be a long
and a unsigned int
.
What differentiates whether (4) or (5) is used is whether the signed type can represent all of the values of the unsigned type.
On a system with a 32 bit
long
and a 16 bitunsigned int
, we'd use case 4We'd use
long
.On a system with a 32 bit
long
and a 32 bitunsigned int
, we'd use case 5 because 4,294,967,295 can be represented by thisunsigned int
, but can't be represented by thislong
.We'd use
unsigned long
.