Opened 9 years ago
Last modified 8 years ago
#9647 new Bugs
BOOST_MPL_ASSERT_RELATION fails to properly handle unsigned types
Reported by: | Robert Ramey | Owned by: | Aleksey Gurtovoy |
---|---|---|---|
Milestone: | To Be Determined | Component: | mpl |
Version: | Boost 1.54.0 | Severity: | Problem |
Keywords: | Cc: |
Description
boost/integer_traits.hpp contains the following
template<> class integer_traits<unsigned long> : public std::numeric_limits<unsigned long>, public detail::integer_traits_base<unsigned long, 0, ULONG_MAX> { };
Problem is that, at least on Clang ULONG_MAX resolves to (through <limits.h>) to be
#define ULONG_MAX (__LONG_MAX__ *2UL+1UL)
But when LONG_MAX resolves to long and the rules of arithmetic promotion result in the expression LONG_MAX *2UL+1UL being a long rather than unsigned long. This causes some funky behavior in cases like:
BOOST_MPL_ASSERT_RELATION( (boost::integer_traits<unsigned long>::const_max), >, (boost::integer_traits<unsigned char>::const_max) );
which fails to compile with "Non-type template argument evaluates to 4294967295, which cannot be narrowed to type 'long'
Change History (6)
comment:1 by , 8 years ago
Summary: | boost_MPL_ASSERT_RELATION fails to properly handle unsigned types → BOOST_MPL_ASSERT_RELATION fails to properly handle unsigned types |
---|
comment:2 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 8 years ago
I'm thinking that this is libc++ version of limits.h
perhaps this is not the correct place to report this.
Robert Ramey
comment:4 by , 8 years ago
I looked into this a little bit more.
First of all, my original guess about problematic type promotions was wrong - I don't think there is any issue with libc++ or anything else in the standard library.
The following test program illustrates my
#include <boost/integer_traits.hpp> #include <boost/mpl/assert.hpp> BOOST_MPL_ASSERT_RELATION( (boost::integer_traits<unsigned long>::const_max), >, (boost::integer_traits<unsigned char>::const_max) ); // compile error under clang enum { x = ( (boost::integer_traits<unsigned long>::const_max) > (boost::integer_traits<unsigned char>::const_max) ) }; // compiles OK - can't figure out why constexpr bool result = ( (boost::integer_traits<unsigned long>::const_max) > (boost::integer_traits<unsigned char>::const_max) ); // compiles fine static_assert(result, "compilation error"); int main(int argc, char * argv[]){ return ! (boost::integer_traits<unsigned long>::const_max > boost::integer_traits<unsigned char>::const_max); }
So I believe this is an issue with MPL_ASSERT_RELATION. I've believe the problem is found in boost/mpl/assert.hpp at the line #329: It's probably deeper than this but I didn't trace it further
Robert Ramey
comment:5 by , 8 years ago
Component: | integer → mpl |
---|
comment:6 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
Is this a problem with Clang, Boost.Mpl or Boost.Integer library?