
On 14 November 2013 05:17, Gavin Lambert wrote:
On 14/11/2013 17:22, Quoth Edward Diener:
Or my own preference of 'static_cast<long>(0xffffffff)'. But using '0xffffffffL' does not work. I admit that understanding the C++ Standard's different interprtetation of these two forms is beyond me.
0xffffffffL is an invalid literal value because it is out of range for the "long" type. (Using UL or even just U would make it valid, but still not the type you wanted.)
It's not invalid, it has the value 4294967295 and a type according to Table 6 in 2.14.2 [lex.icon]. For 32-bit targets it has type unsigned long because 4294967295 doesn't fit in a 32-bit long, and when converted to long it is still a narrowing conversion because the value changes.
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.
An explicit cast on an integer is allowed to reinterpret unsigned to/from signed and/or extend or truncate bits, through long historic usage in C code.
And a type cast is not a context where narrowing conversions are forbidden. The point of introducing narrowing conversions into C++11 was to close some of the holes in the C types system that allow silent, value-changing conversions, but for backwards compatibility to only prevent them in some contexts, e.g. using the new C++11 braced-init syntax or in "converted constant expressions" (as used for non-type template arguments of integral type, see 14.3.2 [temp.arg.nontype] p5.)
(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.