Boost logo

Boost :

Subject: Re: [boost] Regression test relying on undefined compiler behavior (c++11)
From: Chris Cooper (chris.cooper_at_[hidden])
Date: 2014-04-24 11:27:26

[Trying to summarize the history of this discussion]
libs/utility/numeric_traits_test.cpp generates values complement_traits<Number>::min using a clever recursive template, but that template relies on left-shifting a negative value, and according to the C++11 standard that’s a no-no ("the behavior is undefined") which means it’s not a constant expression, which means it can’t be calculated at compile time, which means the BOOST_STATIC_ASSERT in line 332 won’t compile, saying "static_assert expression is not an integral constant expression" (I’m using clang++).

My final proposed solution:

#if !defined(BOOST_NO_LIMITS) && !defined(BOOST_NO_CXX11_CONSTEXPR)
template <class Number> struct complement_traits {
   BOOST_STATIC_CONSTANT(Number, min = std::numeric_limits<Number>::min());
   BOOST_STATIC_CONSTANT(Number, max = std::numeric_limits<Number>::max());
[SNIP] All of the other template definitions for complement_traits, complement_traits_aux, etc.

Kim Barrett improved on this with:

Try boost::integer_traits<Number>::const_min / const_max.
Defined in boost/integer_traits.hpp.

[end of summary]

I have encapsulated this discussion into a boost bug:

Ben Pope, I had the same thought you did (about converting to an unsigned value before doing the left shift) but as I thought about it more, I dislike the whole algorithm that the author of that file (probably David Abrahams) was using. The assumptions implicit in that algorithm (e.g. (SCHAR_MIN << 8) == SHRT_MIN), while true for every platform I’ve worked on, I suspect are not actually part of the C++ standard so I think it’s best to not go down that path.

I think it’s strange the author didn’t use std::numeric_limits or boost::integer_traits, it’s one of those times when I can’t tell whether the author is doing something incredibly clever (and deliberately not using std::numeric_limits and boost::integer_traits) because he is trying to test something specific, or whether the author got so caught up in creating a cool recursive template that he lost track of the actual testing …

Boost list run by bdawes at, gregod at, cpdaniel at, john at