Search code examples
c++charoverflowunsigned-charinteger-promotion

uint8_t operations, when do they overflow?


I'm not sure when I have to worry about overflows when using unsigned chars. This case is clear:

uint8_t a = 3;
uint8_t b = 6;
uint8_t c = a - b; // c is 253 

However, what happens here:

float d = a - b; // d is -3

Are both a and be converted to float before doing the subtraction?

Or also in this case:

float e = (a - b) + (a - c);

Are all three variables converted to float?

Are there possible cases where an overflow can occur, even when the variable being assigned to is a float? Are the rules the same if e is a float, or int, or anything else?

Also, what happens in a case like this:

int a = std::abs(a - b);

Solution

  • Your case is not a result of char-to-float conversions, but is due to the integer promotion rules. Cppreference states the following (emphasis mine):

    Prvalues of small integral types (such as char) may be converted to prvalues of larger integral types (such as int). In particular, arithmetic operators do not accept types smaller than int as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable. This conversion always preserves the value.

    And:

    unsigned char or unsigned short can be converted to int if it can hold its entire value range, and unsigned int otherwise.

    So in your case, the - operator converts the values to integers, which are then converted to floats. Only the assignment to c converts back to a uint8_t (which overflows).

    The same applies to the std::abs example: The values are converted before the subtraction, and the result in passed to the functions.

    For more details on signed/unsigned promotions on arithmetic operations, see for example this answer: https://stackoverflow.com/a/6770275/3198247