[mpl] integral_c [type_traits] integral_constant limits

Hi, I was testing Boost.Ratio with gcc-4.6 c++0x and I get some compile errors when instantiating std::cout << boost::mpl::integral_c< boost::intmax_t, boost::integer_traits<boost::intmax_t>::const_max >::value ; ..\..\..\../boost/mpl/aux_/integral_wrapper.hpp: In instantiation of 'mpl_::integral_c<long long int, 0x7fffffffffffffffll>': ratio_io\ratio_io.pass.cpp:24:6: 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: '-0x8000000000000000ll' is not a valid template argument for type 'long long int' because it is a non-constant expression ..\..\..\../boost/mpl/aux_/integral_wrapper.hpp:72:96: error: '-0x8000000000000000ll' is not a constant expression integral_wrapper.hpp:72 contains typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value + 1)) ) next; The same line pass with gcc-4.6, gcc-4.5 and gcc-4.5 c++0x with just a warning. ..\..\..\../boost/mpl/aux_/integral_wrapper.hpp: In instantiation of 'mpl_::integral_c<long long int, 0x7fffffffffffffffll>': ratio_io\ratio_io.pass.cpp:23:6: instantiated from here ..\..\..\../boost/mpl/aux_/integral_wrapper.hpp:72:96: warning: integer overflow in expression [-Woverflow] integral_c is by integral_constant, but integral_constant doesn't needs next a prior types. This means that with the current implementation we can not use integral_constant with the max value of the type. Do you think this is a bug in integral_constant? Best, _____________________ Vicente Juan Botet Escribá http://viboes.blogspot.com/

This means that with the current implementation we can not use integral_constant with the max value of the type.
Do you think this is a bug in integral_constant?
It's nasty, but we do need MPL support in type_traits, so I don't see what we can really do about this? Can mpl be fixed not to cause numeric overflow when the value is at the limit of the range? John.

----- Original Message ----- From: "John Maddock" <boost.regex@virgin.net> To: <boost@lists.boost.org> Sent: Monday, November 15, 2010 10:17 AM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
This means that with the current implementation we can not use integral_constant with the max value of the type.
Do you think this is a bug in integral_constant?
It's nasty, but we do need MPL support in type_traits, so I don't see what we can really do about this?
Can mpl be fixed not to cause numeric overflow when the value is at the limit of the range?
I gues that it will be enough to overload the next and prior metafunctions on integral_c so the next and prior nestedtypes are no more nedeed, but I don't understand why the compiler is instantiating these types when not used yet. Could someone clarify if this instantiation is conforming to the standard? Vicente

----- Original Message ----- From: "vicente.botet" <vicente.botet@wanadoo.fr> To: <boost@lists.boost.org> Sent: Tuesday, November 16, 2010 10:15 PM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
----- Original Message ----- From: "John Maddock" <boost.regex@virgin.net> To: <boost@lists.boost.org> Sent: Monday, November 15, 2010 10:17 AM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
This means that with the current implementation we can not use integral_constant with the max value of the type.
Do you think this is a bug in integral_constant?
It's nasty, but we do need MPL support in type_traits, so I don't see what we can really do about this?
Can mpl be fixed not to cause numeric overflow when the value is at the limit of the range?
I gues that it will be enough to overload the next and prior metafunctions on integral_c so the next and prior nestedtypes are no more nedeed, but I don't understand why the compiler is instantiating these types when not used yet. Could someone clarify if this instantiation is conforming to the standard?
I have made some modification on Boost.MPL to don't include the prior and next nested types. Instead I have added a 'clone' metafunction that will not be instantiated if not explictly requested and that returns the integral type with a different parameter. template <AUX_WRAPPER_VALUE_TYPE M> struct clone { typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, M) ) type; }; Of course I have needed to change the next and prior metafunctions to use tag dispatch. While running the regression on Boost.MPL I have found a problem: most of the types (iterators) that are used as parameter of next/prior don't have a tag nested type :(. I've added an artificial nested tag type on these types. In this way we are now able to instantiate integral constants with the max and min values without error. boost::mpl::integral_c<boost::intmax_t, 0x7FFFFFFFFFFFFFFFLL> Most of the modified code is protected with the macro BOOST_MPL_NEXT_PRIOR_EXT. I'm not sure this is the best way to workaround this BUG. Please, could you check the attached patches, and let me know if this patch can be included in trunk with minor modifications? Thanks, Vicente PS. Next follows the error when compiling typedef boost::mpl::integral_c<boost::intmax_t, 0x7FFFFFFFFFFFFFFF> T; BOOST_STATIC_ASSERT(T::value == 0x7FFFFFFFFFFFFFFF); with gcc 4.6 gcc.compile.c++ ..\..\..\bin.v2\libs\ratio\test\ratio_add_pass.test\gcc-mingw-4.6.0x\debug\ratio_add_pass.o In file included from ..\..\../boost/mpl/integral_c.hpp:32:0, from ..\..\../boost/mpl/abs.hpp:15, from ..\..\../boost/ratio/ratio.hpp:36, from ..\..\../boost/ratio.hpp:12, from ratio_arithmetic\ratio_add_pass.cpp:16: ..\..\../boost/mpl/aux_/integral_wrapper.hpp: In instantiation of 'mpl_::integral_c<long long int, 0x7fffffffffffffffll>': ratio_arithmetic\ratio_add_pass.cpp:69:5: instantiated from here ..\..\../boost/mpl/aux_/integral_wrapper.hpp:73:96: warning: integer overflow in expression [-Woverflow] ..\..\../boost/mpl/aux_/integral_wrapper.hpp:73:96: error: '-0x8000000000000000ll' is not a valid template argument for type 'long long int' because it is a non-constant expression ..\..\../boost/mpl/aux_/integral_wrapper.hpp:73:96: error: '-0x8000000000000000ll' is not a constant expression "c:\cygwin\gcc-4.6.0\bin\g++.exe" -ftemplate-depth-128 -std=c++0x -O0 -fno-inline -Wall -pedantic -g -Wextra -Wno-long-long -DBOOST_ALL_NO_LIB=1 -DBOOST_ENABLE_WARNINGS -DBOOST_RATIO_USES_MPL_ASSERT -I"..\..\.." -c -o "..\..\..\bin.v2\libs\ratio\test\ratio_add_pass.test\gcc-mingw-4.6.0x\debug\ratio_add_pass.o" "ratio_arithmetic\ratio_add_pass.cpp"

On 1/2/2011 11:00 AM, vicente.botet wrote:
----- Original Message ----- From: "vicente.botet"<vicente.botet@wanadoo.fr> To:<boost@lists.boost.org> Sent: Tuesday, November 16, 2010 10:15 PM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
----- Original Message ----- From: "John Maddock"<boost.regex@virgin.net> To:<boost@lists.boost.org> Sent: Monday, November 15, 2010 10:17 AM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
This means that with the current implementation we can not use integral_constant with the max value of the type.
Do you think this is a bug in integral_constant?
It's nasty, but we do need MPL support in type_traits, so I don't see what we can really do about this?
Can mpl be fixed not to cause numeric overflow when the value is at the limit of the range?
I gues that it will be enough to overload the next and prior metafunctions on integral_c so the next and prior nestedtypes are no more nedeed, but I don't understand why the compiler is instantiating these types when not used yet. Could someone clarify if this instantiation is conforming to the standard?
I have made some modification on Boost.MPL to don't include the prior and next nested types. Instead I have added a 'clone' metafunction that will not be instantiated if not explictly requested and that returns the integral type with a different parameter.
template<AUX_WRAPPER_VALUE_TYPE M> struct clone { typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, M) ) type; };
Of course I have needed to change the next and prior metafunctions to use tag dispatch.
While running the regression on Boost.MPL I have found a problem: most of the types (iterators) that are used as parameter of next/prior don't have a tag nested type :(. I've added an artificial nested tag type on these types.
In this way we are now able to instantiate integral constants with the max and min values without error.
boost::mpl::integral_c<boost::intmax_t, 0x7FFFFFFFFFFFFFFFLL>
Most of the modified code is protected with the macro BOOST_MPL_NEXT_PRIOR_EXT.
I'm not sure this is the best way to workaround this BUG. Please, could you check the attached patches, and let me know if this patch can be included in trunk with minor modifications?
My bug report number 3779 is about this also. Please take a look at it to make sure your fix also addresses that bug report. I assume it does from your description above, but I just want to bring it to your attention just in case.

----- Original Message ----- From: "Edward Diener" <eldiener@tropicsoft.com> To: <boost@lists.boost.org> Sent: Monday, January 03, 2011 3:32 AM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
On 1/2/2011 11:00 AM, vicente.botet wrote:
----- Original Message ----- From: "vicente.botet"<vicente.botet@wanadoo.fr> To:<boost@lists.boost.org> Sent: Tuesday, November 16, 2010 10:15 PM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
I have made some modification on Boost.MPL to don't include the prior and next nested types. Instead I have added a 'clone' metafunction that will not be instantiated if not explictly requested and that returns the integral type with a different parameter.
template<AUX_WRAPPER_VALUE_TYPE M> struct clone { typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, M) ) type; };
Of course I have needed to change the next and prior metafunctions to use tag dispatch.
While running the regression on Boost.MPL I have found a problem: most of the types (iterators) that are used as parameter of next/prior don't have a tag nested type :(. I've added an artificial nested tag type on these types.
In this way we are now able to instantiate integral constants with the max and min values without error.
boost::mpl::integral_c<boost::intmax_t, 0x7FFFFFFFFFFFFFFFLL>
Most of the modified code is protected with the macro BOOST_MPL_NEXT_PRIOR_EXT.
I'm not sure this is the best way to workaround this BUG. Please, could you check the attached patches, and let me know if this patch can be included in trunk with minor modifications?
My bug report number 3779 is about this also. Please take a look at it to make sure your fix also addresses that bug report. I assume it does from your description above, but I just want to bring it to your attention just in case.
Yes. It seems the same problem. The instantiation of prior or next on the limits cause overflow. While this is a warning on most compilers its been error on gcc-4.6.0 C++0x. Could the maintainers of Boost.MPL take a look to the patch attached on this thread? Thanks, Vicente

Vicente Botet wrote
----- Original Message ----- From: "Edward Diener" <eldiener@> To: <boost@.boost> Sent: Monday, January 03, 2011 3:32 AM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
On 1/2/2011 11:00 AM, vicente.botet wrote:
----- Original Message ----- From: "vicente.botet"<vicente.botet@> To:<boost@.boost> Sent: Tuesday, November 16, 2010 10:15 PM Subject: Re: [boost] [mpl] integral_c [type_traits] integral_constant limits
I have made some modification on Boost.MPL to don't include the prior and next nested types. Instead I have added a 'clone' metafunction that will not be instantiated if not explictly requested and that returns the integral type with a different parameter.
template<AUX_WRAPPER_VALUE_TYPE M> struct clone { typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, M) ) type; };
Of course I have needed to change the next and prior metafunctions to use tag dispatch.
While running the regression on Boost.MPL I have found a problem: most of the types (iterators) that are used as parameter of next/prior don't have a tag nested type :(. I've added an artificial nested tag type on these types.
In this way we are now able to instantiate integral constants with the max and min values without error.
boost::mpl::integral_c<boost::intmax_t, 0x7FFFFFFFFFFFFFFFLL>
Most of the modified code is protected with the macro BOOST_MPL_NEXT_PRIOR_EXT.
I'm not sure this is the best way to workaround this BUG. Please, could you check the attached patches, and let me know if this patch can be included in trunk with minor modifications?
My bug report number 3779 is about this also. Please take a look at it to make sure your fix also addresses that bug report. I assume it does from your description above, but I just want to bring it to your attention just in case.
Yes. It seems the same problem. The instantiation of prior or next on the limits cause overflow. While this is a warning on most compilers its been error on gcc-4.6.0 C++0x.
Could the maintainers of Boost.MPL take a look to the patch attached on this thread?
Any new on the application of this patch? Could I apply my self and commit in trunk? Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/mpl-integral-c-type-traits-integral-const... Sent from the Boost - Dev mailing list archive at Nabble.com.

2012/1/4 Vicente Botet <vicente.botet@wanadoo.fr>
Any new on the application of this patch? Could I apply my self and commit in trunk?
Vicente
-- View this message in context: http://boost.2283326.n4.nabble.com/mpl-integral-c-type-traits-integral-const...
Hi, I just bumped into this bug with MinGW-4.8, which treats this as an error. I use boost-1.54 My simple test case is: #include <boost/mpl/integral_c.hpp> typedef boost::mpl::integral_c<int,0x7fffffff>::type next_ovf; typedef boost::mpl::integral_c<int,0x80000000>::type prior_ovf; I worked around my test by doing changing linest 74-75 of boost/mpl/aux_/integral_wrapper.hpp to typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (::boost::intmax_t(value) + 1)) ) next; typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (::boost::intmax_t(value) - 1)) ) prior; This only moves the problem from int to intmax_t, but the workaround works for me ATM. Could this please be fixed? I had this idea of fixing it by providing specializations of integral_c for the limits cases? And the specializations wouldn't typedef the offending next or prior. Would that work? I'd have tried that myself, but this integral_wrapper.hpp file and it's macros scared me away from this idea ;-) Regards, Kris
participants (4)
-
Edward Diener
-
John Maddock
-
Krzysztof Czainski
-
Vicente Botet
-
vicente.botet