Comparison signed and unsigned char

↘锁芯ラ 提交于 2019-12-05 05:22:07

问题


It seems so strange. I found misunderstanding. I use gcc with char as signed char. I always thought that in comparison expressions(and other expressions) signed value converts to unsigned if necessary.

int a = -4;
unsigned int b = a;
std::cout << (b == a) << std::endl; // writes 1, Ok

but the problem is that

char a = -4;
unsigned char b = a;
std::cout << (b == a) << std::endl; // writes 0

what is the magic in comparison operator if it's not just bitwise?


回答1:


According to the C++ Standard

6 If both operands are of arithmetic or enumeration type, the usual arithmetic conversions are performed on both operands; each of the operators shall yield true if the specified relationship is true and false if it is false.

So in this expression

b == a

of the example

char a = -4;
unsigned char b = -a;
std::cout << (b == a) << std::endl; // writes 0

the both operands are converted to type int. As the result signed char propagets its signed bit and two values become unequal.

To demonstrate the effect try to run this simple example

{
    char a = -4;
    unsigned char b = -a;

    std::cout << std::hex << "a = " << ( int )a << "'\tb = " << ( int )b << std::endl;

    if ( b > a ) std::cout << "b is greater than a, that is b is positive and a is negative\n";
}

The output is

a = fffffffc'   'b = 4
b is greater than a, that is b is positive and a is negative

Edit: Only now I have seen that definitions of the variables have to look as

    char a = -4;
    unsigned char b = a;

that is the minus in the definition of b ahould not be present.




回答2:


Since an (unsigned) int is at least 16 bits wide, let's use that for instructional purposes:

In the first case: a = 0xfffc, and b = (unsigned int) (a) = 0xfffc

Following the arithmetic conversion rules, the comparison is evaluated as:

((unsigned int) b == (unsigned int) a) or (0xfffc == 0xfffc), which is (1)


In the 2nd case: a = 0xfc, and b = (unsigned char) ((int) a) or:

b = (unsigned char) (0xfffc) = 0xfc i.e., sign-extended to (int) and truncated

Since and int can represent the range of both the signed char and unsigned char types, the comparison is evaluated as: (zero-extended vs. sign-extended)

((int) b == (int) a) or (0x00fc == 0xfffc), which is (0).


Note: The C and C++ integer conversion rules behave the same way in these cases. Of course, I'm assuming that the char types are 8 bit, which is typical, but only the minimum required.




回答3:


They both output 0 because unsigned values can get converted to signed values, not viceversa (like you said).



来源:https://stackoverflow.com/questions/21027305/comparison-signed-and-unsigned-char

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