繁体   English   中英

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

[英]Reasoning behind “enumeral and non-enumeral type in conditional expression”

由于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
        };
  };

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

请改用:

constexpr int myConstant = 123;

其中int可以是任何符合literal type [我不会尝试在这里定义文字类型 - 它很复杂而谷歌是你的朋友。]

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

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

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

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

编译器告诉您,将枚举值与同一枚举中的另一个值之外的任何值进行比较都是脆弱的代码。

这看起来像海湾合作委员会的一个问题。 这不依赖于-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);
}

在线演示

锵不会发出这一代码的任何警告(除了与-Weverything它抱怨无法访问的代码),但它真的可以说在最后一行的东西。

(GCC 4.9.2,Clang 3.5.0)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM