I bumped into this while writing a program trying to print the constituent byte values of UTF-8 characters.
This is the program that I wrote to test the various ~0
operations:
#include <stdio.h>
int main()
{
printf("%x\n", (char)~0); // ffffffff
printf("%x\n", (unsigned char)~0); // ff
printf("%d\n", sizeof(char) == sizeof(unsigned char)); // 1
printf("%d\n", sizeof(char) == sizeof(unsigned int)); // 0
printf("%d\n", (char)~0 == (unsigned int)~0); // 1
}
I'm struggling to understand why char
would produce an int
-sized value, when unsigned char
produces a char
-sized value.
When passing a type smaller than int
to a variadic function like printf
, it get promoted to type int
.
In the first case, you're passing char
with value -1 whose representation (assuming 2's complement) is 0xff. This is promoted to an int
with value -1 and representation 0xffffffff, so this is what is printed.
In the second case, you're passing an unsigned char
with value 255 whose representation is 0xff. This is promoted to an int
with value 255 and representation 0x000000ff, so this is what is printed (without the leading zeros).