I'm confused. Why in this program a gives me 0xFFFFFFA0 but b gives me 0xA0? It's weird.
#include <stdio.h>
int main()
{
char a = 0xA0;
int b = 0xA0;
printf("a = %x\n", a);
printf("b = %x\n", b);
}
I'm confused. Why in this program a gives me 0xFFFFFFA0 but b gives me 0xA0? It's weird.
#include <stdio.h>
int main()
{
char a = 0xA0;
int b = 0xA0;
printf("a = %x\n", a);
printf("b = %x\n", b);
}
Default type of a
is signed
in char a = 0xA0;
and in any signed data type
whether its char of int
you should be careful of sign bit
, if sign bit
is set
means number will be negative and store as two's compliment
way.
char a = 0xA0; /* only 1 byte for a but since sign bit is set,
it gets copied into remaining bytes also */
a => 1010 0000
|
this sign bit gets copied
1111 1111 1111 1111 1111 1111 1010 0000
f f f f f f A 0
In case of int b = 0xA0;
sign bit(31st bit)
is 0
so what ever it contains i.e 0xA0
will be printed.
Let's take this step-by-step.
char a = 0xA0;
0xA0
in an integer constant with a value of 160 and type int
.
In OP's case, a char
is encoded like a signed char
with an 8-bit range. 160 is more than the maximum 8-bit char
and so assigning an out-of-range value to a some signed integer type is implementation defined behavior. In OP's case, the value "wrapped around" and a
took on the value of 160 - 256 or -96.
// Try
printf("a = %d\n", a);
With printf()
(a variadic function), char a
it passed to the ...
part and so goes though the usual integer promotions to an int
and retains the same value.
printf("a = %x\n", a);
// is just like
printf("a = %x\n", -96);
printf("a = %x\n", a);
With printf()
, "%x"
expect an unsigned
or an int
with a value in the non-negative range. With int
and -96, it is neither and so the output is undefined behavior.
A typical undefined behavior is this case is to interpret the passed bit pattern as an unsigned
. The bit pattern of int
-96, as a 32-bit int
is 0xFFFFFFA0.
Moral of the story:
Enable a compile warnings. A good compiler would warn about both char a = 0xA0;
and printf("a = %x\n", a);
Do not rely on undefined behavior.