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-bitchar
that your C implementation uses. 128 is converted tochar
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 anint
. 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 thanint
, as it is in most C implementations, the integer promotions convert achar
to anint
, per 6.3.1.1 2: “If anint
can represent all values of the original type…, the value is converted to anint
…”Thus, in
printf("c1: %x, c2: %x\n", c1, c2);
, anint
value of −128 is passed as the second argument. Your C implementation uses 32-bit two’s complement forint
, 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
isunsigned int
. However, your C implementation has accepted theint
and reinterpreted its bits as anunsigned 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 toprintf
. 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 becausec1
was given the value −128 as explained above, andc2 = -128;
also assigns the value −128 toc2
, soc1
andc2
have the same value.