Boost logo

Boost :

Subject: Re: [boost] [mpl] clang error for narrowing from unsigned int 0xffffffff to long
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2013-11-14 18:41:00


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.)


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk