cintegerprintfbyteuint8t

About the use of uint8_t in C when counting


I wanted to make sure that I understood what is happening in the following code:

#include <stdio.h>
#include <stdint.h>

int main (void)
{
    uint8_t a = 255;

    a = a + 5;

    printf("%d\n", a);
}

Will the printed value be 4 'cause when a reaches the maximum value it can count to (255) it resets back to 0? And so, if I want to continue counting after a (255), I could create an int variable and add a to it? Like int b = a + 5; that would print 260.


Solution

  • Yes to both questions.

    Given that a is a uint8_t, a + 5 is equivalent to (int)a + 5 and produces an int.

    When doing arithmetic on pairs of values, the usual arithmetic conversions are performed. If the type of both values are integer types, then this refers to performing the integer promotion of both operands, plus additional steps if the promoted values are still of different types.

    Integer promotion refers to converting a value with a type of lesser rank than int into an int (if their whole range can fit in an int) or an unsigned int. uint8_t is guaranteed to be a type of lesser rank than int, and its range is guaranteed to fit in an int, so a value of that type will get promoted into an int.

    So, because of the usual arithmetic conversions, a + 5 converts a to an int, adds int 5 to it, producing int 260.

    So far, no overflow. But then we assign it to a uint8_t. Converting an overly large a value into an unsigned integer type is well defined. For an 8-bit unsigned integer, you effectively get the result mod 256, which is uint8_t 4.

    There would be no overflow if you stored int 260 into an int instead, so that will indeed produce int 260.