Signed and unsigned char

空扰寡人 提交于 2021-02-05 05:25:52

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!