An integer overflow in an enumeration when in a template class

Delving into metaprogramming patterns, I discovered strange behavior with a range of enumerations in C ++. I get a warning: an integer overflow in an expression when it looks like I really don't want a value that goes beyond the enumeration. Here is the code:

#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;
}

Compilation output:

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

Program output:

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

Why does an enumeration in the pow class have a smaller range? As far as I understand, for each value of "i" I have an instance of another class, so it has a separate enumeration type. Therefore, for 'i'> 31, the enumeration must be 64 bits, for example test_2. Where am I mistaken?
I tried gcc 4.8 and gcc 5.4 and the results are the same.

+4
1

cppreference.com


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*\};

. , , .

0

All Articles