Search code examples
cintegerchar

Why doesn't `char` lose data when an `int` is being assigned to it?


I'm a novice C programmer. I defined two variables int x = 0xffffffff and char y = x, thereafter I printed that using the printf("%x\n", y) function; I was expecting something like ff on the terminal, instead it printed ffffffff onto the screen. I'm wondering how can a char store 4 bytes of storage, when the storage size of a char is 1.

#include <stdio.h>

int main(void) {
    int x = 0xffffffff;
    char y = x;
    printf("%x\n", y);

    return 0;
}

Solution

  • There's actually a fair amount of thing going on here. First:

    int x = 0xffffffff;
    

    The integer constant 0xffffffff has a value of 4,294,967,295 (i.e. 232-1) and a type of unsigned int, assuming an int is 32 bit.

    This unsigned int value is then converted to int for the initialization. This undergoes an implementation-defined conversion, which in most cases results in the value -1 being assigned. This value happens to have the same representation as the original value in two's complement.

    Then on this line:

    char y = x;
    

    We're initializing y with the value -1. This value is in the range of a char (assuming char is signed) so there is no change in value when converting from int to char in this case. Assuming two's complement representation, this is represented as 0xff.

    Then when you print:

    printf("%x\n", y);
    

    Because printf is a variadic function, the argument y which has type char is promoted to type int before being passed to the function. As before, both types can store the value -1 so the value is unchanged.

    The %x format specifier expects an argument of type unsigned int. Since an int was passed instead of an unsigned int this is technically undefined behavior, however it's unlikely a signed/unsigned mismatch would cause an issue on any real implementation.

    That being the case, the int value of -1 has a representation of 0xffffffff which when interpreted as an unsigned int would have that value, so ffffffff is what is printed.

    So to answer your question:

    how can a char store 4 bytes of storage, when the storage size of a char is 1.

    It doesn't. It just appears that way due to conversions and representations of the relevant types.