[mpl] integral constant overflow

Hi, I've recently started studying the book "c++ template meta programming" (I like it a lot!) and one of my own exercises was to get an integral type's max/min value. To get the type's maximal value I've created a metafunction max_val; Compiling the code below with vc++2008 warning level 2+ yields the warning "truncation of constant value" or "integral constant overflow" if I use an int instead of a char. <code> namespace mpl = boost::mpl; template<typename T> struct significant_bits: mpl::int_<std::numeric_limits<T>::digits> {}; template<typename T> struct max_val_impl: mpl::accumulate< mpl::range_c<int, 1, significant_bits<T>::value>, mpl::integral_c<T, 1>, mpl::next<mpl::plus<mpl::_1, mpl::_1> > > {}; template<typename T> struct max_val: max_val_impl<T>::type { BOOST_MPL_ASSERT((boost::is_integral<T>)); }; int main() { const char maxval = max_val<char>::value; return 0; } </code> The problematic metafunction instantiation boils down to mpl::integral_c<char, 127> where mpl::integral_c<char, 127>::next results in 128 which is then truncated. Of course I can turn off the compiler warnings but since the warning happens in integral_wrapper.hpp and the integral constant stuff is included in many other files including the boost type traits it would be tedious to always remember to include integral_c.hpp explicitly before any other headers with the warnings turned off. I don't know whether there is a really satisfying option, just wanted to discuss this point. Klaus Triendl

on Sat Feb 16 2008, klaus triendl <klaus-AT-triendl.eu> wrote:
Hi,
I've recently started studying the book "c++ template meta programming" (I like it a lot!) and one of my own exercises was to get an integral type's max/min value.
To get the type's maximal value I've created a metafunction max_val;
Compiling the code below with vc++2008 warning level 2+ yields the warning "truncation of constant value" or "integral constant overflow" if I use an int instead of a char.
<code> namespace mpl = boost::mpl;
template<typename T> struct significant_bits: mpl::int_<std::numeric_limits<T>::digits> {};
template<typename T> struct max_val_impl: mpl::accumulate< mpl::range_c<int, 1, significant_bits<T>::value>, mpl::integral_c<T, 1>, mpl::next<mpl::plus<mpl::_1, mpl::_1> > > {};
template<typename T> struct max_val: max_val_impl<T>::type { BOOST_MPL_ASSERT((boost::is_integral<T>)); };
int main() { const char maxval = max_val<char>::value; return 0; } </code>
The problematic metafunction instantiation boils down to mpl::integral_c<char, 127> where mpl::integral_c<char, 127>::next results in 128 which is then truncated.
Of course I can turn off the compiler warnings but since the warning happens in integral_wrapper.hpp and the integral constant stuff is included in many other files including the boost type traits it would be tedious to always remember to include integral_c.hpp explicitly before any other headers with the warnings turned off.
I don't know whether there is a really satisfying option, just wanted to discuss this point.
Hi Klaus, It's undefined behavior to overflow a signed integral type in C++. The only solution is to "not do that." HTH, -- Dave Abrahams Boost Consulting http://boost-consulting.com
participants (2)
-
David Abrahams
-
klaus triendl