Reputation: 2591
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
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
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
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 char
s, so they'll be promoted in the same manner and are directly comparable.
Upvotes: 4
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