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

Jordan Rose jordan_rose at apple.com
Thu Nov 14 09:08:52 PST 2013


On Nov 13, 2013, at 19:53 , Edward Diener <eldlistmailingz at tropicsoft.com> wrote:

> On 11/13/2013 7:59 PM, Karen Shaeffer wrote:
>> On Wed, Nov 13, 2013 at 04:29:27PM -0700, Richard wrote:
>>> 
>>> In article <l610fi$4sj$3 at ger.gmane.org>,
>>>     Edward Diener <eldlistmailingz at tropicsoft.com> writes:
>>> 
>>>> Is not -1 in the range of an 'int' ?
>>> 
>>> Yes, but you didn't write -1 in your source file.
>>> 
>>>> Is not 0xffffffff equivalent to -1
>>>> as a signed value ?
>>> 
>>> No.  They are two different integer literals.
>>> 
>>>> What am I missing here ?
>>> 
>>> Read the mentioned section of the standard carefully.  I've read this
>>> part and it isn't particularly confusing or difficult.
>> 
>> 
>> Hello,
>> My interpretation of this is that 2.14.2 defines how the compiler interprets the
>> literal. That isn't the problem though. The problem arises, when you attempt to
>> implicitly convert the compiler's interpretation to a signed integer. And the
>> error is narrowing. clang emits this error:
>> 
>> hexLiteralsUnsigned.cpp:16:24: error: constant expression evaluates to 4294967295 which cannot be
>>       narrowed to type 'int' [-Wc++11-narrowing]
>>     signed int isigned{0xFFFFFFFF};
>> 
>> You can avoid this error by simply using a cast:
>> signed int isigned{static_cast<signed int>(0xFFFFFFFF)};
>> 
>> FYI, g++-4.8.1 only emits a warning about the narrowing, then successfully completes the
>> compilation. Based on the standard section 8.5.4, I believe clang is correct to emit the
>> error. And 5.17.9 declares an assignment, such as 'int i = {0XFFFFFFFF};' to be a narrowing
>> error as well. I believe clang is correct to emit a narrowing error.
> 
> That is OK, now that I understand it. Interesting enough, however, if I use '0xffffffffL' I still get an error from clang but if I use 'static_cast<long>(0xffffffff)' everything is fine. That is a difference I would never have suspected, but at least I know now it is there.

It helps if you stop thinking about hex constants as bit patterns, because the compiler doesn’t at that point. It interprets a hex constant in the same way your math teacher would. Only when it has to assign a type (including via the ‘L’ suffix) does it then try to truncate/reinterpret that value as signed or unsigned.

One way in which this surfaces is that you can use hex constants in the preprocessor, which doesn’t have types:

#if 0xffffffff > 0
#warning “hex is positive”
#else
#warning “hex is negative"
#endif

Jordan



More information about the cfe-dev mailing list