Opened 7 years ago

Last modified 8 months ago

#6546 new Bugs

mpl::constant_c does not support min and max values for signed types

Reported by: smr@… Owned by: Aleksey Gurtovoy
Milestone: To Be Determined Component: mpl
Version: Boost Development Trunk Severity: Problem
Keywords: Cc: viboes

Description

Boost.Ratio test fails on debian linux with gcc 4.6.

gcc.compile.c++ ../../../bin.v2/libs/ratio/test/ratio_add_pass.test/gcc-4.6/debug/ratio_add_pass.o
In file included from ../../../boost/mpl/integral_c.hpp:32:0,
                 from ../../../boost/ratio/detail/mpl/abs.hpp:15,
                 from ../../../boost/ratio/ratio.hpp:36,
                 from ratio_arithmetic/ratio_add_pass.cpp:16:
../../../boost/mpl/aux_/integral_wrapper.hpp: In instantiation of ‘mpl_::integral_c<long int, 9223372036854775807l>’:
../../../boost/ratio/detail/mpl/abs.hpp:38:29:   instantiated from ‘boost::mpl::abs_tag<mpl_::integral_c<long int, 9223372036854775807l> >’
../../../boost/ratio/detail/mpl/abs.hpp:44:8:   instantiated from ‘boost::mpl::abs<mpl_::integral_c<long int, 9223372036854775807l> >’
../../../boost/ratio/detail/mpl/abs.hpp:58:8:   instantiated from ‘boost::mpl::abs_c<long int, 9223372036854775807l>’
../../../boost/ratio/ratio.hpp:79:74:   instantiated from ‘const intmax_t boost::ratio<9223372036854775807l, 1l>::ABS_N’
../../../boost/ratio/ratio.hpp:81:5:   instantiated from ‘boost::ratio<9223372036854775807l, 1l>’
../../../boost/ratio/detail/overflow_helpers.hpp:227:95:   instantiated from ‘const intmax_t boost::ratio_detail::ratio_add<boost::ratio<9223372036854775807l, 1l>, boost::ratio<-0x00000000000000001l, 1l> >::gcd_n1_n2’
../../../boost/ratio/detail/overflow_helpers.hpp:243:18:   instantiated from ‘boost::ratio_detail::ratio_add<boost::ratio<9223372036854775807l, 1l>, boost::ratio<-0x00000000000000001l, 1l> >’
../../../boost/ratio/ratio.hpp:136:8:   instantiated from ‘boost::ratio_add<boost::ratio<9223372036854775807l, 1l>, boost::ratio<-0x00000000000000001l, 1l> >’
ratio_arithmetic/ratio_add_pass.cpp:70:37:   instantiated from here
../../../boost/mpl/aux_/integral_wrapper.hpp:72:96: warning: integer overflow in expression [-Woverflow]
../../../boost/mpl/aux_/integral_wrapper.hpp:72:96: error: overflow in constant expression [-fpermissive]
../../../boost/mpl/aux_/integral_wrapper.hpp:72:96: note: in template argument for type ‘long int’ 

Change History (6)

comment:1 Changed 7 years ago by Steve Robbins <smr@…>

There are similar failures for a dozen other tests, and it appears on both the Sandia and Debian gcc 4.6 testing systems; see http://www.boost.org/development/tests/release/developer/ratio.html

comment:2 Changed 7 years ago by viboes

Status: newassigned

Hi,

this is know issue on the Boost.Mpl which instantiates the next and the previous number. I've proposed a patch long time ago (since I started to use gcc-4.6) but it has not been applied. I will see what can I do.

comment:3 Changed 7 years ago by viboes

Cc: viboes added
Component: ratiompl

comment:4 Changed 7 years ago by viboes

Owner: changed from viboes to Aleksey Gurtovoy
Status: assignednew

comment:5 Changed 8 months ago by Matthijs Kooijman <matthijs@…>

This bug still seems to exist (I tried today's mpl git master). The essence, as indicated in the mailing list thread above, is that mpl::integral_c cannot support the minimum and maximum values of signed types, since the compiler does not allow defining the prior and next values, since that would cause signed overflow which is undefined.

The error shown in the original report is about using ratio, but this bug can be easily reproduced on by instantiating mpl::integral_c directly:

#include <boost/mpl/integral_c.hpp>
typedef boost::mpl::integral_c<int32_t,0x7fffffff>::type next_ovf_32;
typedef boost::mpl::integral_c<int32_t,0x80000000>::type prior_ovf_32;
typedef boost::mpl::integral_c<int64_t,0x7fffffffffffffff>::type next_ovf_64;
typedef boost::mpl::integral_c<int64_t,0x8000000000000000>::type prior_ovf_64; 

Which leads to these errors (only one of four shown).

In file included from foo.cpp:1:0:
mpl/include/boost/mpl/aux_/integral_wrapper.hpp: In instantiation of ‘struct mpl_::integral_c<long int, -9223372036854775808l>’:
foo.cpp:6:59:   required from here
mpl/include/boost/mpl/aux_/integral_wrapper.hpp:73:88: warning: integer overflow in expression [-Woverflow]
     typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior;
                                                                                 ~~~~~~~^~~~
mpl/include/boost/mpl/integral_c.hpp:31:54: note: in definition of macro ‘AUX_WRAPPER_INST’
 #define AUX_WRAPPER_INST(value) AUX_WRAPPER_NAME< T, value >
                                                      ^~~~~
mpl/include/boost/mpl/aux_/integral_wrapper.hpp:73:31: note: in expansion of macro ‘BOOST_MPL_AUX_STATIC_CAST’
     typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior;
                               ^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from mpl/include/boost/mpl/integral_c.hpp:32:0,
                 from foo.cpp:1:
mpl/include/boost/mpl/aux_/integral_wrapper.hpp:73:96: error: overflow in constant expression [-fpermissive]
     typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior;
                                                                                                ^~~~~
mpl/include/boost/mpl/aux_/integral_wrapper.hpp:73:96: error: overflow in constant expression [-fpermissive]
mpl/include/boost/mpl/aux_/integral_wrapper.hpp:73:96: note: in template argument for type ‘long int’

Solutions proposed in that thread are:

  • Convert to intmax_t before doing the +1 or -1. This is easy, but only fixes things for types smaller than intmax_t, leaves the problem for intmax_t and probably introduces the problem for uintmax_t. Post nr8 from Krzysztof Czainski in the above linked mailing list thread has an example implementation.
  • Specialize integral_c for these limiting values, leaving out the next or prior member. Post nr8 from Krzysztof Czainski in the above linked mailing list thread suggests this.
  • Remove the next and prior members from integral_c and use tag dispatch for them instead. Post nr4 by Vicente Botet in the above linked mailing list thread has a patch.

#3779 seems to be a duplicate of this bug.

comment:6 Changed 8 months ago by Matthijs Kooijman <matthijs@…>

Summary: ratio_arithmetic/ratio_add_pass fails to compilempl::constant_c does not support min and max values for signed types
Version: Boost Release BranchBoost Development Trunk
Note: See TracTickets for help on using tickets.