Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the == operator to compare a char to 0x80 always results in false?

char byte = 0x80
if(byte == 0x80)
{
    cout << "This message never gets printed!";
}

The hexadecimal value 0x80 is equivalent in binary to 1000 0000, which clearly fits in a byte.

However, the compiler warns me about the line with the conditional:

warning: comparison is always false due to limited range of data type

Why is the result of the conditional false in this case?

Is 0x80 getting expanded in the conditional to something like 0x80000000?

Is it possible to use the == operator to check if a char equals 0x80?

like image 604
Cory Klein Avatar asked Jan 12 '23 20:01

Cory Klein


1 Answers

The problem is that char is, in the C and C++ standards, defined that it can be either a signed or an unsigned value, and that a char must have at least 8 bits. The architecture and compiler in question appears to use signed 8-bit char values.

This means that any value with the highest bit (bit 7) will be a negative value. So 0x80 as a char becomes -128 decimal.

The constant 0x80 is not a char value, it is an int value.

So when you compare -128 with 0x80 (128) they are not the same, and can never be, and the compiler figures this out and issues a warning.

There are a variety of ways to achieve this, here are a few possible scenarios:

First, we can cast either value to the type of the other:

if (((int)byte) & 0xff == 0x80)

or

if (byte == (char)0x80) 

Alternatively, we can make the constant into a char value, rather than an int value.

if (byte == '\200')     // Octal 200 = 0x80. 

or

if (byte == '\x80')

Alternatively, use an unsigned char byte = 0x80; - specifying that it's an unsigned char will ensure that it doesn't "flip to negative".

like image 116
Mats Petersson Avatar answered Jan 18 '23 22:01

Mats Petersson