On Nov 13, 2013, at 11:47 , Edward Diener
<eldlistmailingz@tropicsoft.__com
<mailto:eldlistmailingz@tropicsoft.com>
<mailto:eldlistmailingz@__tropicsoft.com
<mailto:eldlistmailingz@tropicsoft.com>>>
wrote:
I am seeing this error when testing Boost MPL with clang
using the VC++
RTL:
"bitwise.cpp(40,25) : error: non-type template argument
evaluates to
4294967295, which cannot be narrowed to type 'long'
[-Wc++11-narrowing]
MPL_ASSERT_RELATION( (bitor_<_0,_ffffffff>::value), ==,
0xffffffff );"
The typedefs are:
typedef integral_c<unsigned int, 0> _0;
typedef integral_c<unsigned int, 0xffffffff> _ffffffff;
The bitor_ in the Boost MPL is evaluating constants at
compile time,
doing a bitwise or ('|').
Why does clang think that 0xffffffff is a 'long' when
used in the
comparison ? According to the C++ standard the type of
0xffffffff is the
first of int, unsigned int, long, unsigned long, long
long, unsigned
long long in which its value can fit ( section 2.14.2 ).
Is this a clang
bug ?
Sorry, the problem is not as I had assumed above. It is
actually
because the MPL_ASSERT_RELATION macro devolves down to a
template
class where the values are of type 'long'. Is there
something in C++11
which says that implicit conversion of a value from an
'unsigned int'
to a 'long' is illegal ? That is what clang is telling me
but I can
find no such restriction in the C++11 standard regarding this.
I think it’s more likely that on Windows ‘long’ is the same size
as
‘int’, and so you have an overflow error. You need to fix the
template…which I guess means submitting a patch to Boost.
I tried a patch of the test code where I set:
typedef integral_c<int, 0xffffffff> _ffffffff;
but clang still complains that:
bitwise.cpp(23,24) : error: non-type template argument evaluates to
4294967295, which cannot be narrowed to type 'int' [-Wc++11-narrowing]
typedef integral_c<int, 0xffffffff> _ffffffff;
This I do not understand. Why does 0xffffffff evaluate to 4294967295
rather than -1 ? Where in the C++ standard does it say that hex
literals are unsigned values by default ?
Nothing to do with hex literals, just literals in general. If they don't
fit in the range of an int, the literal is of unsigned int type so it
can fit the value.