“条件表达式中的数字和非数字类型”背后的推理

时间:2015-04-16 20:30:18

标签: c++ c++11 coding-style

由于C ++ 11转换GCC在条件表达式中输出警告“枚举和非枚举类型”。我想了解这个警告背后的原因。比较枚举常量有什么危险?

显然我们可以通过

摆脱这个警告
  • -Wno-enum-compare
  • 通过显式转换为整数类型

但为什么麻烦?就个人而言,我总是努力编写警告免费代码,通常默认发出的警告是非常明智的。例如,它认为比较有符号和无符号整数是危险的。

但是使用枚举广泛使用惯用的C ++元编程。我不知道任何替代方案,它具有类似的可读性,简明扼要,并且不需要任何实际存储。

引用一个具体的例子:以下元函数可能出现什么问题,以便警告就足够了?

template<class TYPES>
struct MaxSize;
template<>
struct MaxSize<NullType>
  {
    enum{ value = 0 };
  };
template<class TY, class TYPES>
struct MaxSize<Node<TY,TYPES> >
  {
    enum{ thisval = sizeof(TY)
        , nextval = MaxSize<TYPES>::value
        , value   = nextval > thisval?  nextval:thisval
        };
  };

2 个答案:

答案 0 :(得分:2)

如果您使用枚举作为定义编译时常量值的方法,则可以立即停止执行此操作。

请改用:

constexpr int myConstant = 123;

其中int可以是符合literal type条件的任何内容[我不会尝试在此处定义文字类型 - 它很复杂且Google是您的朋友。] < / p>

或者甚至在c ++ 11之前你可以说:

class Foo{
    static const int myConstant = 123;
 };

其中int可以是任何整数类型。

除非你需要myConstant的地址,否则不需要在cpp文件中有相应的定义。

编译器告诉您将枚举值与同一枚举中的其他值进行比较是脆弱的代码。

答案 1 :(得分:2)

这看起来像海湾合作委员会的一个问题。这不依赖于-std=c++11选项。警告不是与比较有关,而是与条件运算符有关。

似乎只有当一个枚举成员使用无符号值进行初始化,而另一个成员使用另一个枚举值初始化时,才会发出警告。此外,警告仅在枚举成员的初始化中发出。

我设法将代码删除到以下内容:

enum A { valueA = 1 };

enum B { 
    // if you change 0u to 0, there'll be no warning
    thisval = 0u, 
    // if you change valueA to any integral constant, there'll be no warning
    nextval = valueA, 
    // warning on this line
    value = nextval > thisval ? nextval : thisval,
    // no warning here
    value2 = nextval > thisval
};

int main() {
    // no warning here
    (void)(nextval > thisval ? nextval : thisval);
    // the same warning also here - but not with Clang
    (void)(nextval > thisval ? nextval : false);
}

Online demo

Clang没有对此代码发出任何警告(除了-Weverything抱怨无法访问的代码),尽管它可能在最后一行上说了些什么。

(GCC 4.9.2,Clang 3.5.0)