模板类中枚举中的整数溢出
Integer overflow in enum when in template class
深入研究模板元编程,我发现c++中枚举的范围有一个奇怪的行为。我得到一个警告:表达式中的整数溢出,当看起来我实际上不想要超出enum范围的值时。下面是代码:
#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
为什么类pow中的enum有一个较小的范围?据我所知,对于每个' I '值,我都实例化了一个不同的类,因此它在其中有一个单独的枚举类型。因此,对于'i'> 31, enum应该是64位,就像test_2一样。我哪里错了?
我尝试了gcc 4.8和gcc 5.4,结果是一样的。
From cppreference.com
Unscoped枚举
enum name { enumerator = constexpr , enumerator = constexpr , ... }
(1)
(…)
1)声明一个基础类型不固定的无作用域枚举类型(在本例中,基础类型为 int,或者,如果不是所有枚举数值都可以表示为int,则声明一个实现定义的更大的整数类型,可以表示所有枚举数值。如果枚举数列表为空,则底层类型就像该枚举只有一个值为0的枚举数一样。
因此,在模板中,编译器似乎选择int,最大值为+-2147483648(31位+ 1为符号)。在test
中,编译器似乎认识到这是不够的,并选择unsigned int
的最大值为4294967296(32位)。在test _2
中,编译器认为这也不够,并选择64位的无符号类型(最大18446744073709551616)。
将枚举声明为
enum { result = 2*pow<i-1>::result, randomMax = *insert anything large here*};
就可以了。第二个值只需要强制编译器选择一个足够长的类型来保存您需要的所有值。
相关文章:
- 整数溢出,最大值为 pow(10,19)
- 模函数,避免C++整数溢出
- 优化正在杀死我在 clang 6 中的整数溢出检查
- 从双精度转换为整数的显式类型是否始终检查整数溢出?
- 运行时错误:有符号整数溢出:964632435 * 10 无法在类型 'int' 中表示
- 我很难理解这些关于检测整数溢出的评论
- 检测 32 位整数溢出
- 如何在没有整数溢出的情况下找到n%(k*k)
- C 中俄罗斯农民算法中的整数溢出
- 检查Android NDK COD中的整数溢出
- 对于特定情况的整数溢出似乎是由整数溢出引起的错误
- 如何修复整数溢出警告
- 整数溢出 C++ 即使使用“无符号长整型”也是如此
- 整数溢出是否会影响其他变量
- 为什么功能不给整数溢出
- 有符号整数溢出、内部函数和未定义的行为
- 整数溢出不会发生:它们从0重新启动
- 以下程序中最大 int 1000 000(在 int 范围内)的整数溢出
- 为什么Turbo C Wraparound每次签名的整数溢出,尽管签名的整数溢出是不确定的
- 编译器是否有可能检测整数溢出或其他数据类型溢出的可能性