1

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?

2
  • 1
    hi, does stackoverflow.com/questions/46073295/… answer your question? Commented Aug 14, 2024 at 12:09
  • Before the bitwise complement, the value of num2 is promoted to an int, with the value 0x000000ff (assuming 32-bit int). When you then complement it, you get 0xffffff00 which is indeed not equal to 0. Commented Aug 14, 2024 at 12:11

1 Answer 1

1

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));
Sign up to request clarification or add additional context in comments.

1 Comment

or printf("%d\n", num1 == (uint8_t)~num2);

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.