加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 模板类中枚举时的整数溢出

发布时间:2020-12-16 06:52:08 所属栏目:百科 来源:网络整理
导读:深入研究模板元编程我在C中发现了一系列枚举的奇怪行为.我得到一个警告:表达式中的整数溢出,当它看起来我实际上不想要一个超出枚举范围的值.这是代码: #include iostream#include limitstemplate int iclass pow {public: enum { result = 2*powi-1::resul
深入研究模板元编程我在C中发现了一系列枚举的奇怪行为.我得到一个警告:表达式中的整数溢出,当它看起来我实际上不想要一个超出枚举范围的值.这是代码:

#include <iostream>
#include <limits>

template <int i>
class pow {
public:
        enum { result = 2*pow<i-1>::result};
};

template<>
class pow<0> {
public:
        enum { result = 1};
};

enum test { one,max = 4294967295 };
enum test_2 { last = 4294967295*2 };

int main() {
        std::cout << "pow<2>: t" << pow<2>::result << std::endl;
        std::cout << "pow<4>: t" << pow<4>::result << std::endl;
        std::cout << "pow<30>: t" << pow<30>::result << std::endl;
        std::cout << "pow<31>: t" << pow<31>::result << std::endl;
        std::cout << "max test: t" << 
                std::numeric_limits<std::underlying_type<test>::type>::max() << std::endl;
        std::cout << "max test_2: t" << 
                std::numeric_limits<std::underlying_type<test_2>::type>::max() << std::endl;
        return 0;
}

编译输出:

test.cpp:7:19: warning: integer overflow in expression [-Woverflow]
  enum { result = 2*pow<i-1>::result};
                   ^
test.cpp:7:7: warning: overflow in constant expression [-fpermissive]
  enum { result = 2*pow<i-1>::result};

节目输出:

pow<2>:         4
pow<4>:         16
pow<30>:        1073741824
pow<31>:        -2147483648
max test:       4294967295
max test_2:     18446744073709551615

为什么课堂上的enum范围较小?据我所知,对于每个’i’值,我有一个不同的类实例化,所以它有一个单独的枚举类型.因此,对于’i’> 31,枚举应该是64位,就像test_2一样.哪里错了?
我尝试了gcc 4.8和gcc 5.4,结果是一样的.

解决方法

从 cppreference.com起

Unscoped enumeration
enum name { enumerator = constexpr,enumerator = constexpr,... }(1)
(…)
1) Declares an unscoped enumeration type whose underlying type is not fixed (in this case,the underlying type is either int or,if not all enumerator values can be represented as int,an implementation-defined larger integral type that can represent all enumerator values. If the enumerator-list is empty,the underlying type is as if the enumeration had a single enumerator with value 0).

所以在模板中你的编译器似乎选择了int,最大值为-2147483648(符号为31位1).在测试中,编译器似乎认识到这还不够,选择unsigned int,最大值为4294967296(32位).在test _2中,编译器认识到这也是不够的,并选择64位无符号类型(最大值18446744073709551616).

将你的枚举声明为

enum { result = 2*pow<i-1>::result,randomMax = *insert anything large here*};

应该做的伎俩.第二个值只需强制编译器选择一个足够长的类型来保存所需的所有值.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读