This might be a very basic problem, but I couldn't manage to. Here is what I am working with.
#include <stdio.h>
int main(void)
{
char c1, c2;
int s;
c1 = 128;
c2 = -128;
s = sizeof(char);
printf("size of char: %d\n", s);
printf("c1: %x, c2: %x\n", c1, c2);
printf("true or false: %d\n", c1 == c2);
}
The result is like this.
size of char: 1
c1: ffffff80, c2: ffffff80
true or false: 1
i assigned the value 128 to signed(normal) char type, but it didn't overflow.
In additon, c1 and c2 both seems to hold 4bytes, and -128 and 128 are the same value.
How can I understand these facts? I need your help. Thank you very much.
In c1 = 128;
, 128 does not fit in the signed eight-bit char
that your C implementation uses. 128 is converted to char
per C 2018 6.5.16.1 2: “the value of the right operand is converted to the type of the assignment expression…”
The conversion is implementation-defined, per 6.3.1.3 3: “Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.” Your C implementation converted 128, which is 100000002 as an unsigned binary numeral, to −128, which is represented with the same bits when using two’s complement for signed binary. Thus, the result is that c1
contains the value −128.
In printf("c1: %x, c2: %x\n", c1, c2);
, c1
is converted to an int
. This is because the rules for calling functions with ...
parameters are to apply the default argument promotions to the corresponding arguments, per 6.5.2.2 7: “The default argument promotions are performed on trailing arguments.”
The default argument promotions include the integer promotions, per 6.5.2.2 6. When the range of char
is narrower than int
, as it is in most C implementations, the integer promotions convert a char
to an int
, per 6.3.1.1 2: “If an int
can represent all values of the original type…, the value is converted to an int
…”
Thus, in printf("c1: %x, c2: %x\n", c1, c2);
, an int
value of −128 is passed as the second argument. Your C implementation uses 32-bit two’s complement for int
, in which −128 is represented with the bits 11111111111111111111111110000000, which we can express in hexadecimal as ffffff80.
The format string specifies a conversion using %x
. The proper argument type for %x
is unsigned int
. However, your C implementation has accepted the int
and reinterpreted its bits as an unsigned int
. Thus, the bits 11111111111111111111111110000000 are converted to the string “ffffff80”.
This explains why “ffffff80” is printed. It is not because c1
has four bytes but because it was converted to a four-byte type before being passed to printf
. Further, the conversion of a negative value to that four-byte type resulted in four bytes with many bits set.
Regarding c1 == c2
evaluating to true (1), this is simply because c1
was given the value −128 as explained above, and c2 = -128;
also assigns the value −128 to c2
, so c1
and c2
have the same value.