While debugging my implementation of YMODEM on an embedded system, I noticed that some code comparing a uint8_t and the inverse of a uint8_t is not behaving as I expected, but I don't really understand why. To test that this is really the case in C and not just wierd behaviour of my embedded system, I wrote the following
#include <stdio.h>
#include <stdint.h>
int main(int argc, char ** argv)
{
uint8_t num1 = 0;
uint8_t num2 = 255;
printf("%d\n", num1 == ~num2);
return 0;
}
If I have a uint8_t with the value 0x00, then the inverse should be 0xFF, right? So this program should print 1. However, it prints 0, indicating that 0x00 != ~0xFF.
Why does this happen?
What you're seeing is a result of integer promotion.
In most expressions, anytime a type smaller than int
is used it is first promoted to type int
. The ==
operator and the ~
operator are cases where this applies.
So in the expression ~num2
, the value of num2
(with representation 0xff) is first promoted to type int
while retaining the same value and having a representation of 0x000000ff. Then when the ~
operator is applied the result has type int
with representation 0xffffff00. This value is not equal to 0, so the comparison fails.
You'll need to mask off any upper bits after the ~
operator is applied.
printf("%d\n", num1 == (~num2 & 0xff));