quantum231
quantum231

Reputation: 2591

Char comparison with 0xFF returns false even when it is equal to it, why?

In C++ program I have some char buf[256]. The problem is here:

if (buf[pbyte] >= 0xFF)
    buf[++pbyte] = 0x00;

This always returns false even when buf[pbyte] is equal to 255 AKA 0xFF as seen in immediate window and watch window. Thus the statement does not get executed. However, when I change this to below:

if (buf[pbyte] >= char(0xFF))
    buf[++pbyte] = 0x00;

The program works; how come?

Upvotes: 2

Views: 1706

Answers (4)

Baum mit Augen
Baum mit Augen

Reputation: 50081

The problem is that char is signed on your system.

In the common 2s complement representation, a signed char with the "byte-value" 0xFF represents the integer -1, while 0xFF is an int with value 255. Thus, you are effectively comparing int(-1) >= int(255), which yields false. Keep in mind that they are compared as int because of arithmetic conversion rules, that is both operands are promoted ("cast implicitly") to int before comparing.

If you write char(0xFF) however, you do end up with the comparison -1 >= -1, which yields true as expected.

If you want to store numbers in the range [0,255], you should use unsigned char or std::uint8_t instead of char.

Upvotes: 2

Vlad from Moscow
Vlad from Moscow

Reputation: 311078

Due to the integer promotions in this condition

if (buf[pbyte] >= `0xFF`)

the two operands are converted to the type int (more precisely only the left operand is converted to an object of the type int because the right operand already has the type int). As it seems in your system the type char behaves as the type signed char then the value '\xFF' is a negative value equal to -1. Then this value is converted to an object of the type int you will get 0xFFFFFFFF (assuming that the type int occupies 4 bytes).

On the other hand the integer constant 0xFF is a positive value that has internal representation like 0x000000FF

Thus the condition in the if statement

if ( 0xFFFFFFFF >= `0x000000FF`)

yields false.

When you use the casting ( char )0xFF then the both operands have the same type and the same values.

Upvotes: 1

Adrian McCarthy
Adrian McCarthy

Reputation: 48022

The literal 0xFF is treated as an int with the value 255.

When you compare a char to an int, the char is promoted to an int before the comparison.

On some platforms char is a signed value with a range like -128 to +127. On other platforms char is an unsigned value with a range like 0 to 255.

If your platform's char is signed, and its bit pattern is 0xFF, then it's probably -1. Since -1 is a valid int, the promotion stops there.

You end up comparing -1 to 255.

The solution is to eliminate the implicit conversions. You can write the comparison as:

if (buf[pbyte] == '\xFF') ...

Now both sides are chars, so they'll be promoted in the same manner and are directly comparable.

Upvotes: 4

mascoj
mascoj

Reputation: 1319

Integer literals by default are converted to an int, assuming the value will fit into the int type, otherwise it is promoted to a long.

So in your code you are specifying 0xFF which is interpreted as an int type, i.e. 0x000000FF

Upvotes: 0

Related Questions