Home > OS >  C usual arithmetic conversions rules
C usual arithmetic conversions rules

Time:03-09

... the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:

  1. If both operands have the same type, then no further conversion is needed.
  2. 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.
  3. 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.
  4. 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.
  5. 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 bit unsigned int, we'd use case 4

    We'd use long.

  • On a system with a 32 bit long and a 32 bit unsigned int, we'd use case 5 because 4,294,967,295 can be represented by this unsigned int, but can't be represented by this long.

    We'd use unsigned long.

  • Related