Detect when multiple enum items map to same value(检测多个枚举项何时映射到相同的值)
问题描述
是否有一种编译时方法来检测/防止 C/C++ 枚举中的重复值?
Is there a compile-time way to detect / prevent duplicate values within a C/C++ enumeration?
问题在于有多个项目被初始化为显式值.
背景:
我继承了一些 C 代码,例如:
I've inherited some C code such as the following:
#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
.
The problem is that as the code grows & as developers add more messages to the MsgFoo1x
group, eventually it overruns BASE2_VAL
.
这段代码最终会迁移到 C++,所以如果有一个仅限 C++ 的解决方案(模板魔术?),那没问题——但是一个适用于 C 和 C++ 的解决方案更好.
This code will eventually be migrated to C++, so if there is a C++-only solution (template magic?), that's OK -- but a solution that works with C and C++ is better.
推荐答案
有几种方法可以检查此编译时间,但它们可能并不总是适合您.首先在 MsgFoo2A 之前插入一个标记"枚举值.
There are a couple ways to check this compile time, but they might not always work for you. Start by inserting a "marker" enum value right before 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
Now we need a way to ensure that MARKER_1_DONT_USE < BASE2_VAL
at compile-time. There are two common techiques.
声明大小为负的数组是错误的.这看起来有点难看,但确实有效.
It is an error to declare an array with negative size. This looks a little ugly, but it works.
extern int IGNORE_ENUM_CHECK[MARKER_1_DONT_USE > BASE2_VAL ? -1 : 1];
如果 MARKER_1_DONT_USE 大于 BASE_2_VAL,几乎所有编写过的编译器都会产生错误.GCC 吐槽:
Almost every compiler ever written will generate an error if MARKER_1_DONT_USE is greater than BASE_2_VAL. GCC spits out:
test.c:16: error: size of array ‘IGNORE_ENUM_CHECK’ is negative
静态断言
如果您的编译器支持 C11,您可以使用 _Static_assert
.对 C11 的支持并不普遍,但您的编译器无论如何都可能支持 _Static_assert
,尤其是因为 C++ 中的相应特性得到广泛支持.
Static assertions
If your compiler supports C11, you can use _Static_assert
. Support for C11 is not ubiquitous, but your compiler may support _Static_assert
anyway, especially since the corresponding feature in C++ is widely supported.
_Static_assert(MARKER_1_DONT_USE < BASE2_VAL, "Enum values overlap.");
GCC 发出以下消息:
GCC spits out the following message:
test.c:16:1: error: static assertion failed: "Enum values overlap."
_Static_assert(MARKER_1_DONT_USE < BASE2_VAL, "Enum values overlap.");
^
这篇关于检测多个枚举项何时映射到相同的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:检测多个枚举项何时映射到相同的值


基础教程推荐
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 从 std::cin 读取密码 2021-01-01