Consider the following:
unsigned int i1 = 0xFFFFFFFF;
unsigned char c1 = i1;
char c2 = i1;
printf("%x\n", i1); // 0xFFFFFFFF as expected
printf("%x\n", c1); // 0xFF as expected
printf("%x\n", c2); // 0xFFFFFFFF ????
printf("%d\n", c1 == c2); // false ????
I know, one should not assign an int
to a char
. Anyway, look how c2
seems to be storing more than a byte. What I expected was a copy of the "less significant byte" of n1
into c2
. Am I wrong to assume this? Is there no copy at all? Why does the behavior of unsigned char
differs from char
?
I actually found this in a very concrete situation while using gethostbyname(). It returns a struct which contains a field char *h_addr
storing an ipv4 address (four 8 bit long numbers). I wanted to print the ip address as numbers but got abnormally large results.
I know a workaround, masking with i1 & 0xFF
works but I would like to understand the issue.
In your system the type char
behaves as the type signed char
.
After this assignment
char c2 = n1;
Note: It seems there is a typo and you mean
char c2 = i1;
the variable c2 has the value 0xff
that is -1
.
In this call
printf("%x\n", c2);
the argument expression c2
is converted to the type int
propagating the sign bit due to the integer promotions. And this value is outputted according to the format %x
.
Pay attention to that you need to write
printf( "%x\n",( unsigned int ) c2 );
because the conversion specifier x
expects an object of the type unsigned int
.
If you want to get the expected by you result you need output the objects as objects of character types using conversion modifier hh
. For example
#include <stdio.h>
int main(void)
{
unsigned int i1 = 0xFFFFFFFF;
unsigned char c1 = n1;
char c2 = n1;
printf( "%x\n", i1 );
printf( "%hhx\n", c1 );
printf( "%hhx\n", c2 );
}
The program output is
ffffffff
ff
ff
Also it seems you made a typo and wrote
printf("%d\n", n3 == n2);
instead of
printf("%d\n", c1 == c2);
If so then again the operands of the comparison operator are implicitly converted to the type int
due to the integer promotions. As the operand c1
has the type unsigned char
then it is converted to the value 0x000000FF
while the operand c2
as it stores a negative value is converted to the value 0xFFFFFFFF
. So the result values are not equal to each other.
User contributions licensed under CC BY-SA 3.0