What you see happening is a result of the rules of integer promotions. Anytime a variable smaller than an int
is used in an expression the value is promoted to type int
.
Suppose bufi[i]
contains the value 255. The hex representation of this is 0xFF
. This value is then operand of the ~
operator. So the value will first be promoted to int
which (assuming it is 32 bit) will have the value 0x000000FF
, and applying ~
to this gives you 0xFFFFFF00
. You then compare this value with buf[i]
which is of type uint8_t
. The value 0xFFFFFF00
is outside of this range so the comparison will always be false.
If you assign the result of the ~
back to a variable of type uint8_t
, the value 0xFFFFFF00
is converted to 0x00
. It is this converted value that is then compared against buf[i]
.
So the behavior you see is not the result of an optimization but the rules of the language. Using a temp variable as you are is one way to address this issue. You could also cast the result to uint8
:
if(buf[i] != (uint8)(~bufi[i]))
Or mask out all but the lowest order byte:
if(buf[i] != (~bufi[i] & 0xff))