c++ - 检测多个枚举项何时映射到相同的值

标签 c++ c enums duplicates

是否有一种编译时方法来检测/防止 C/C++ 枚举中的重复值?

问题是有多个项目被初始化为显式值

背景:

我继承了一些 C 代码,如下所示:

#define BASE1_VAL    (5)
#define BASE2_VAL    (7)

typedef enum
{
  MsgFoo1A = BASE1_VAL,       // 5
  MsgFoo1B,                   // 6
  MsgFoo1C,                   // 7
  MsgFoo1D,                   // 8
  MsgFoo1E,                   // 9
  MsgFoo2A = BASE2_VAL,       // Uh oh!  7 again...
  MsgFoo2B                    // Uh oh!  8 again...
} FOO;

问题在于,随着代码的增长和开发人员向 MsgFoo1x 组添加更多消息,最终它会超出 BASE2_VAL

此代码最终将迁移到 C++,因此如果有一个仅 C++ 的解决方案(模板魔术?),那没关系 - 但与 C 和 C++ 一起使用的解决方案更好。

最佳答案

有几种方法可以检查此编译时间,但它们可能并不总是适合您。首先在 MsgFoo2A 之前插入一个“标记”枚举值。

typedef enum
{
    MsgFoo1A = BASE1_VAL,
    MsgFoo1B,
    MsgFoo1C,
    MsgFoo1D,
    MsgFoo1E,
    MARKER_1_DONT_USE, /* Don't use this value, but leave it here.  */
    MsgFoo2A = BASE2_VAL,
    MsgFoo2B
} FOO;

现在我们需要一种方法来确保 MARKER_1_DONT_USE < BASE2_VAL在编译时。有两种常见的技术。

负大小数组

声明一个负大小的数组是错误的。这看起来有点难看,但确实有效。

extern int IGNORE_ENUM_CHECK[MARKER_1_DONT_USE > BASE2_VAL ? -1 : 1];

如果 MARKER_1_DONT_USE 大于 BASE_2_VAL,几乎所有编写过的编译器都会产生错误。 GCC 吐槽:

test.c:16: error: size of array ‘IGNORE_ENUM_CHECK’ is negative

静态断言

如果您的编译器支持 C11,您可以使用 _Static_assert .对 C11 的支持并不普遍,但您的编译器可能支持 _Static_assert无论如何,特别是因为 C++ 中的相应功能得到了广泛的支持。

_Static_assert(MARKER_1_DONT_USE < BASE2_VAL, "Enum values overlap.");

GCC 吐出以下信息:

test.c:16:1: error: static assertion failed: "Enum values overlap."
 _Static_assert(MARKER_1_DONT_USE < BASE2_VAL, "Enum values overlap.");
 ^

关于c++ - 检测多个枚举项何时映射到相同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2576868/

相关文章:

c++ - 从 QMainWindow 中访问 QDockWidget 的小部件

c++ - 为什么 GCC 在将未初始化的 volatile 指针转换到 `void` 时发出警告?

c - 为什么 puts() 函数中的指针在以下代码的第 4 行中不起作用?虽然第 1 行正在运行

c - 从 dll 导出函数指针

mysql - 按所有枚举值分组而不指定枚举值

java - 在java中,这样的枚举类型编译成什么?

c++ - SSE2 指令在 C++ 的内联汇编中不起作用

c++ - 在 GLSL 中重新使用内置 OpenGL 变量定义自己的制服。为什么?

使用c从一个txt文件复制到另一个txt文件

enums - 有没有办法在 Rust 中使用 "flatten"枚举进行(反)序列化?