0

In the following c-code, the function func1 decides which element of enumerate ENUM1 is given as input.
In the first call func1(ENUM_ELEMENT1); it works as expected but in the second and third calls the results are wrong (it is expected that the function prints ENUM_ELEMENT2 and ENUM_ELEMENT3 respectively but in both cases it prints ENUM_ELEMENT1)!

  #include <stdio.h>
  #include <stdint.h>

  typedef enum
  {
      ENUM_ELEMENT1 = 0x0000001u,
      ENUM_ELEMENT2 = 0x0000002u,
      ENUM_ELEMENT3 = 0x0000004u,
      ENUM_ELEMENT4 = 0x0000008u,
  } ENUM1;

  void func1( uint32_t inp )
  {
      if (0u != inp & ENUM_ELEMENT1)
      {
          printf("ENUM_ELEMENT1\n");
      }
      else if (0u != inp & ENUM_ELEMENT2)
      {
          printf("ENUM_ELEMENT2\n");
      }
      else if (0u != inp & ENUM_ELEMENT3)
      {
          printf("ENUM_ELEMENT3\n");
      }
      else if (0u != inp & ENUM_ELEMENT4)
      {
          printf("ENUM_ELEMENT4\n");
      }
  }

  int main( void )
  {
      func1(ENUM_ELEMENT1);       // prints ENUM_ELEMENT1    --> correct
      func1(ENUM_ELEMENT2);       // prints ENUM_ELEMENT1    --> wrong!
      func1(ENUM_ELEMENT3);       // prints ENUM_ELEMENT1    --> wrong!
      getchar();
      return 0;
  }
DevSolar
  • 67,862
  • 21
  • 134
  • 209
Ben2400
  • 41
  • 4
  • does it work now? – Alan Jul 30 '18 at 06:33
  • it works as I explained, in the 2nd and 3rd cases wrong result! – Ben2400 Jul 30 '18 at 06:34
  • 3
    ...and that is why you should *always* use parenthesis to group your logic expressions. You might not remember operator precedence as well as you might think... and even if you do, it makes things easier for the next guy who might not. – DevSolar Jul 30 '18 at 06:36
  • yes, you are right, thanks – Ben2400 Jul 30 '18 at 06:37
  • I prefer `if (inp & ENUM_ELEMENT1) { /*...*/ }`, avoiding a redundant implicit comparison with `0` and avoiding possible extra unneeded conversions. – pmg Jul 30 '18 at 06:48

1 Answers1

3

It's a matter of operator precedence.

The expression 0u != inp & ENUM_ELEMENT1 is equal to (0u != inp) & ENUM_ELEMENT1. If inp is non-zero then 0u != inp will be true, which is convertible to the integer 1, and 1 & 1 is indeed "true".

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621