char c = -1;
printf("%02X\n", c);
This has undefined behavior.
The %X
format requires an argument of type unsigned int
. You're passing an argument of type char
, which is (almost certainly) promoted to int
.
So you're printing a value of type int
with a value outside the range of the expected type, unsigned int
. This is where you get undefined behavior.
(There's no portable way to print a signed integer type in hexadecimal, unless you write your own code to do it. %x
and %X
, which print hexadecimal, require an unsigned argument. The decimal formats are %d
for signed and %u
for unsigned.)
Note that type char
itself may be unsigned in some implementations so your initialization
char c = -1;
doesn't have undefined behavior, but it can store an implementation-defined value (probably 255) in c
.
If you want to print a byte value in hexadecimal, you probably want to use unsigned char
rather than plain char
. And you'll want to convert it to the expected type when passing it to printf
, because unsigned char
is also (almost certainly) promoted to (signed) int
).
unsigned char c = 255;
printf("c = %02X\n", (unsigned int)c);
If you want to print a char
value in hexadecimal, you can use this slightly convoluted code:
char c = -1;
printf("c = %02X\n", (unsigned char)c);
The cast to unsigned char
ensures that the value is is in the range 0..255; ensures that the value is not promoted from char
to int
. The unsigned char
value is promoted to int
, which is then treated as an unsigned int
value by the %02X
format. (int
and unsigned int
arguments are interchangeable, but only for values in the range of both types.)