Search code examples
cunsigned-integer

How does an unsigned integer and literal get compared in C?


I'm doing the following comparison:

uint32_t value = 1000;

if(value < 100)
{
  // do something
}

What get's casted to what in this case? Does 'value' get casted to an integer? Does 100 get casted to an integer or unsigned integer?


Solution

  • First, all numeric constant have a type. In the case of the constant 100, because it is decimal, has no suffix, and can fit in the range of an int, the constant has type int.

    How the comparison is performed is dictated by the usual arithmetic conversions. Specifically, the conversion rules for integer types are specified in section 6.3.1.8p1 of the C standard as follows:

    ... 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

    Assuming an int on your platform is 32 bits, that makes uint32_t the same as an unsigned int, so you're using a signed type and an unsigned type of the same size in an expression. That being the case, the third bullet point above applies, namely the value 100 (which has type int) is converted to an unsigned int and then the values are compared.

    In this case, the value 100 is also within the range of an unsigned int, so there is no conversion of the actual value. If it was instead something like -100, that value is not in the range of an unsigned int, which means the value would be converted to be within that range. Again, assuming a 32 bit int the value would be 232 - 100.