|
Boost : |
Subject: Re: [boost] [mpl] clang error for narrowing from unsigned int 0xffffffff to long
From: Edward Diener (eldiener_at_[hidden])
Date: 2013-11-14 19:04:50
On 11/14/2013 6:41 PM, Gavin Lambert wrote:
> On 14/11/2013 23:02, Quoth Jonathan Wakely:
>>> 0xffffffff does not explicitly specify a size so the compiler is
>>> allowed to
>>> pick one itself; it will probably infer "unsigned int", as "signed
>>> int" is
>>> too small. (Or on platforms where "int" is 16-bit, it would infer
>>> "unsigned
>>> long".)
>>
>> The compiler doesn't get to pick, again Table 6 says what its type is.
>
> That counts as the compiler picking the type, because on different
> platforms a different result occurs, and it has a wider range to choose
> from without the suffix. As I said, on 16-bit platforms it would pick
> "unsigned long" and on 32-bit platforms it would pick "unsigned int".
>
>>> (Technically that usage should ideally require reinterpret_cast
>>> instead of
>>> static_cast, since you're reinterpreting the sign bit. But again I
>>> think
>>> tradition won out here -- and it's a less scary conversion than other
>>> places
>>> you need reinterpret_cast.)
>>
>> No, reinterpret_cast between different integer types is ill-formed.
>> Only the conversions listed in [expr.reinterpret.cast] are allowed.
>
> I know that, that wasn't my point. I wasn't saying that
> reinterpret_cast is valid according to the standard, I was saying that
> the internalised meaning of reinterpret_cast in most people's heads
> ("interpret the underlying raw bit storage of this variable as this
> other type") is closer in behaviour to what static_cast on a same-size
> integer type actually does (at least in most implementations), vs. what
> static_cast does when performing any other conversion (eg. integer to
> float alters the bit pattern, pointer to other pointer might return a
> different pointer value, etc).
>
> I'm not even saying that this is wrong -- part of the reason to make the
> cast types explicit over the C-style casts was to more clearly call out
> the places where you're doing "scary" things (aka reinterpret_cast), to
> enhance type safety and stamp out void* -- and integer conversions
> aren't sufficiently scary (although arguably they're still something you
> need to pay almost as much attention to -- while they're less likely to
> crash or UB if used wrong than bad pointer casts, they can still produce
> incorrect results).
>
> (And I might be wrong about this [as I haven't looked at C++11 changes
> in detail] but IIRC the standard does not actually guarantee that ints
> are in two's-complement form, so the integer static_cast might not be
> reversible, although I think a lot of code assumes it is.)
I think that you are right that the standard says nothing about two's
complement notation. It does seem a pretty safe bet that the cast is
reversible between 'unsigned int' and 'long' since the 'long' is
guaranteed to be at least the size in bits of the 'unsigned int'.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk