问题
Why are two char like signed char
and unsigned char
with the same value not equal?
char a = 0xfb;
unsigned char b = 0xfb;
bool f;
f = (a == b);
cout << f;
In the above code, the value of f
is 0.
Why it's so when both a
and b
have the same value?
回答1:
There are no arithmetic operators that accept integers smaller than int
. Hence, both char values get promoted to int
first, see integral promotion
for full details.
char
is signed on your platform, so 0xfb
gets promoted to int(-5)
, whereas unsigned char
gets promoted to int(0x000000fb)
. These two integers do not compare equal.
On the other hand, the standard in [basic.fundamental] requires that all char types occupy the same amount of storage and have the same alignment requirements; that is, they have the same object representation and all bits of the object representation participate in the value representation. Hence, memcmp(&a, &b, 1) == 0
is true
.
回答2:
The value of f
and, in fact, the behaviour of the program, is implementation-defined.
In C++14 onwards1, for a signed
char
, and assuming that CHAR_MAX
is 127
, a
will probably be -5
. Formally speaking, if char
is signed
and the number does not fit into a char
, then the conversion is implementation-defined or an implementation-defined signal is raised.
b
is 251
.
For the comparison a == b
(and retaining the assumption that char
is a narrower type than an int
) both arguments are converted to int
, with -5
and 251
therefore retained.
And that's false
as the numbers are not equal.
Finally, note that on a platform where char
, short
, and int
are all the same size, the result of your code would be true
(and the ==
would be in unsigned
types)! The moral of the story: don't mix your types.
1 C++14 dropped 1's complement and signed magnitude signed char
.
回答3:
- Value range for (signed)
char
is[-128, 127]
. (C++14 drops -127 as the lower range). - Value range for
unsigned char
is[0, 255]
What you're trying to assign to both of the variables is 251
in decimal. Since char
cannot hold that value you will suffer a value overflow, as the following warning tells you.
warning: overflow in conversion from 'int' to 'char' changes value from '251' to ''\37777777773'' [-Woverflow]
As a result a
will probably hold value -5
while b
will be 251
and they are indeed not equal.
来源:https://stackoverflow.com/questions/51749197/signed-and-unsigned-char