[cfe-dev] Error when testing clang with VC++ RTL and Boost MPL

Edward Diener eldlistmailingz at tropicsoft.com
Wed Nov 13 16:35:04 PST 2013


On 11/13/2013 6:24 PM, James Dennett wrote:
> On Wed, Nov 13, 2013 at 3:03 PM, Edward Diener
> <eldlistmailingz at tropicsoft.com> wrote:
>> On 11/13/2013 5:08 PM, David Blaikie wrote:
>>>
>>>
>>>
>>>
>>> On Wed, Nov 13, 2013 at 1:58 PM, Edward Diener
>>> <eldlistmailingz at tropicsoft.com
>>> <mailto:eldlistmailingz at tropicsoft.com>> wrote:
>>>
>>>      On 11/13/2013 2:59 PM, Jordan Rose wrote:
>>>
>>>
>>>          On Nov 13, 2013, at 11:47 , Edward Diener
>>>          <eldlistmailingz at tropicsoft.__com
>>>          <mailto:eldlistmailingz at tropicsoft.com>
>>>          <mailto:eldlistmailingz at __tropicsoft.com
>>>
>>>          <mailto:eldlistmailingz at tropicsoft.com>>>
>>>          wrote:
>>>
>>>              On 11/13/2013 9:46 AM, Edward Diener 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.
>>
>>
>> Is not -1 in the range of an 'int' ?
>
> Yes.
>
>> Is not 0xffffffff equivalent to -1 as a
>> signed value ?
>
> I'm not sure that's even a well-formed question.  0xffffffff (on a
> 32-bit platform) is _not_ a signed value, so it's not _anything_ "as a
> signed value".  In a context that requires a converted constant
> expression, it's not convertible to a signed int (because its value is
> not in the range of int -- its value is 2^31-1, not -1).

I think you meant 2^32 - 1,

In two's complement notation 0xffffffff is equal to -1 as a signed 
32-bit integer and 4294967295 ( 2^32 - 1 ) as an unsigned 32-bit 
integer. Since an  integer comes before an unsigned integer in 2.14.2 
paragraph 2 of the C++ standard for the type of a hex literal I would 
have expected 0xffffffff to be of type 'int' unless otherwise specified. 
But what you seem to be saying is that the value of a hexadecimal ( or 
octal ) literal is always calculated as its actual value as a positive 
amount and only then is a type assigned based on whether that value can 
fit into the first of the series of types given in 2.14.2 paragraph 2. 
If that is the case my understanding of how this works is my own 
confusion, and I am glad to be enlightened. Thanks !




More information about the cfe-dev mailing list