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?