c - 如何在 C 中模拟强类型枚举?

标签 c enums

在 C++03 中,可以模拟 strongly typed enum通过将它放在一个类(或 namespace )中:

struct MyEnum
{
  enum enumName
  {
    VALUE_1 = 1,
    VALUE_2,
  };
};

并使用它:

MyEnum::enumName v = MyEnum::VALUE_1;

是否可以在 C 中做类似的事情?如果是,如何?


我这样试过,但当然不行:

struct A
{
  enum aa
  {
    V1 = 5
  };
};

int main()
{
  A::aa a1 = A::V1;
  enum A::aa a2 = A::V1;
  struct A::aa a3 = A::V1;

  return 0;
}

最佳答案

这是我的解决方案。与@Eric 的设计相比有一些优势:

  • 支持相等性测试(例如 A_VALUE_0 == value)
  • 不依赖于 C99 的复合文字
  • 可以转换为枚举分配不正确的值。

缺点:

  • 标志不起作用(例如 A_VALUE_0 | A_VALUE_1)
  • 不能切换
  • 在测试相等性时可能会使 IDE 混淆错误行的位置(例如 A_VALUE_0 == B_VALUE_1)

注意事项:

  • 永远不要取消引用这种类型的指针。会比兰博基尼更容易撞车

这是实现(使用 -Werror-pedantic 编译):

typedef struct A { char empty[1]; } *A; // we use 'empty' so that we don't get a warning that empty structs are a GNU extension
#define A_VALUE_0 ((A) 0x1)
#define A_VALUE_1 ((A) 0x2)
#define A_VALUE_2 ((A) 0x4)

typedef struct B { char empty[1]; } *B;

#define B_VALUE_0 ((B) 0x0)
#define B_VALUE_1 ((B) 0x1)
#define B_VALUE_2 ((B) 0x2)

int main()
{
    A a = A_VALUE_0;

    int equal = (a == A_VALUE_1); // works!
    int euqal = (a == B_VALUE_1) // doesn't work

    A flags = A_VALUE_0 | A_VALUE_1; // doesn't work!

    switch (a) { // doesn't work
        case A_VALUE_0:
            puts("value 0");
            break;
        case A_VALUE_1:
            puts("value 1");
            break;
        case A_VALUE_2:
            puts("value 2");
            break;
        default:
            puts("unknown value");
            break;
    } // doesn't work

    // casting works for assignment:
    A b = (A) (B_VALUE_2);

    return 0;
}

关于c - 如何在 C 中模拟强类型枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11903625/

相关文章:

c - JNA 写入 stdout 时内存访问无效

python - 如何从覆盆子模拟 dualshock 3 垫的按钮按下

c++ - C/C++ 编译器能否通过 pthread 库调用合法地将变量缓存在寄存器中?

c - 按位移动问题

delphi - 集合类型是否适合循环迭代?

c++ - Typedef C++ 中的位域/掩码

c - 多线程 C 程序中的共享字段是否大量使用 CPU?

c++ - std::vector 持有类方法

sql - SQL中ENUM列的大小?

c# - 静态变量应该用枚举代替吗?