C++:如何检查枚举值是否唯一

3

我们使用的是VS 2008。

有一个很大的枚举,由许多开发人员填充。

这个枚举有一个__int64类型(一个Microsoft扩展),我想让编译器报告枚举中非唯一值。

如果它是一个普通的枚举,我会像这样做:

enum E1
{
    E11 = 0x01F00,
    E12 = 0x01F00,
    E13
};
#pragma warning(push)
#pragma warning(error: 4061)
#pragma warning(error: 4062)
void F(E1 e1)
{
    switch (e1)
    {
    case E11:
    case E12:
    case E13:
        return;
    }
}
#pragma warning(pop)

如果E1有两个相同的值,函数F将会出错。

如果开发人员忘记将新值添加到switch中,它也会出现另一个错误。

但是我的枚举类型为__int64(或long long)。

当我尝试为E1 e1执行相同的switch时,它会截断值并抱怨差异为0x100000000或0x200000000的值。

如果我将e1强制转换为__int64,则编译器不会抱怨,即使开发人员忘记将新值添加到switch中(因此整个检查函数变得无用)。

问题是:有没有人知道我该怎么做?或者VS 2008(或C ++)是否有另一种工具来确保枚举:__int64只有唯一的值?


2
我能想到的最好方法是“不要明确指定值(除第一个值之外)”。 - Mark B
@Mark 有时候枚举很有用,因为编译器会在 switch 中警告你是否漏掉了某个值。另一方面,这些值本身也可以用于其他目的(不仅仅是区分情况)。 - Yury
@Mark,这些值是标志(0x000..01、0x00..02、0x00..04等)。 - Alek86
这个回答解决了你的问题吗?C/C++枚举:如何检测多个项映射到相同值的情况 - phuclv
显示剩余3条评论
2个回答

2

根据您的评论,我假设您的枚举本身没有聚合(组合)标志。在这种情况下,您可以使用两个枚举来使错误更难发生。您仍然可以规避编译器,但我认为这不是真正的问题。

enum Bit_Index
{
    FLAG1_INDEX,
    FLAG2_INDEX,
    FLAG_FANCY_INDEX,
    LAST_INDEX
};

#define DECLARE_BIT_VALUE(att) att##_VALUE = 1ULL << att##_INDEX
enum Bit_Value
{
    DECLARE_BIT_VALUE(FLAG1),
    DECLARE_BIT_VALUE(FLAG2),
    DECLARE_BIT_VALUE(FLAG_FANCY),

    // Declared NOT using the macro so we can static assert that we didn't forget
    // to add new values to this enum.
    LAST_BIT   // Mainly a placeholder to prevent constantly having to add new commas with new ids.
};
#undef DECLARE_BIT_VALUE

然后在实现文件中使用 static_assert 来确保枚举值不会错位:

// Make sure to the best of our abilities that we didn't mismatch the index/bit enums.
BOOST_STATIC_ASSERT((LAST_BIT - 1) == (1U << (LAST_INDEX - 1)));

好主意。我可以用 switch 检查第一个枚举(并希望其他人以同样的方式使用第二个枚举)。这并不是 100% 的保证,但比什么都没有要好得多。谢谢。 - Alek86

0
有人知道我该怎么办吗?
另一个答案可能是算法分析。静态分析不一定是寻找安全漏洞。不幸的是,在这种情况下,您将不得不使用外部工具来验证您的约束条件。我可以帮助您实现这一点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接