[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