使用枚举作为常量时 c 编译器的意外行为

unexpected behaviour of c compiler when using enumerate as constant

在下面的 C 代码中,函数 func1 决定枚举 ENUM1 的哪个元素作为输入。
在第一次调用中 func1(ENUM_ELEMENT1); 它按预期工作,但在第二次和第三次调用中结果是错误的(预计该函数分别打印 ENUM_ELEMENT2ENUM_ELEMENT3 但是在这两种情况下,它都会打印 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;
  }

这是operator precedence的事情。

表达式 0u != inp & ENUM_ELEMENT1 等于 (0u != inp) & ENUM_ELEMENT1。如果 inp 非零,则 0u != inp 为真,可转换为整数 1,而 1 & 1 确实为 "true".