Search code examples
cenumeration

unexpected behaviour of c compiler when using enumerate as constant


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;
  }

Solution

  • 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".