为什么编译器不会抱怨错误的枚举值

时间:2013-02-04 16:05:32

标签: c++

#include <iostream>

enum IsOptionAEnum
{
    IsOptionA_YES,
    IsOptionA_NO
};

enum IsOptionBEnum
{
    IsOptionB_YES,
    IsOptionB_NO
};

void TestFunc(IsOptionAEnum optionA, IsOptionBEnum optionB)
{
    if (optionA == IsOptionA_YES || optionA == IsOptionB_YES) // typo
    {
        // ...
    }

    //if (optionA == IsOptionA_YES || optionB == IsOptionB_YES) // correct one
    //{
    //}

}

问题&GT; optionA的类型为IsOptionAEnum,其值不为IsOptionB_YES。为什么VS2010的编译器没有找到这个错误?

如果是编译器无法找到错误的情况,有没有办法可以强制执行此限制,以便编译器可以找到错误?

3 个答案:

答案 0 :(得分:5)

Pre-C ++ 11,枚举类型不提供您正在寻找的类型安全性,并且本质上是非常整数。

你想要强类型的枚举类:
http://www.cprogramming.com/c++11/c++11-nullptr-strongly-typed-enum-class.html

答案 1 :(得分:5)

虽然标准不会使这个错误(枚举实际上是整数的语法),但这肯定是编译器可以检测到的。 Clang,使用-Wenum-compare进行编译,提供:

Bonsai:~ adamw$ clang++ test.cpp 
    test.cpp:15:45: warning: comparison of two values with different enumeration
      types ('IsOptionAEnum' and 'IsOptionBEnum') [-Wenum-compare]
    if (optionA == IsOptionA_YES || optionA == IsOptionB_YES) // typo
                                    ~~~~~~~ ^  ~~~~~~~~~~~~~

默认情况下,Visual C ++可能不会对此发出警告。尝试在编译器上设置/Wall标志,这将启用所有警告。如果它仍未发出警告,您可以向VC编译器团队提交请求。

编辑:正如其他答案和评论所提到的,如果你有VC11,你可以使用Strongly typed enums

答案 2 :(得分:1)

非C ++ 11解决方案是使用struct s

struct IsOptionAEnum
{
    int val;
    static IsOptionAEnum IsOptionA_YES;
    static IsOptionAEnum IsOptionA_NO;

    IsOptionAEnum( int v ): val(v) {}
};

IsOptionAEnum::IsOptionA_YES(0);
IsOptionAEnum::IsOptionA_YES(1);

if( optionA == IsOptionAEnum::IsOptionA_YES ) // this is type-safe
    // etc.

如果您不需要它,可以删除内部值(您需要禁用复制,始终通过引用传递并比较结构的地址)。

在C ++ 11中,你可以像Prashant所建议的那样使用typed enums