Casting between signed and unsigned
Is this safe:
int main()
{
boost::int16_t t1 = 50000; // overflow here.
boost::uint16_t t2 = (boost::uint16_t)t1;
std::cout << t1 << " " << t2 << std::endl;
开发者_运维技巧}
To be even more specific: I'm storing this data in a table which is using signed types in its schema, is it safe to store, and retrieve this data in this manner?
Thanks!
No, I believe this is implementation defined. From the C++ draft standard, §4.7/3
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.
This applies to the first statement. int16_t
is signed, and it can not represent 50000. So the value of t1
depends on the implementation.
Once you know t1
, t2
is guaranteed by §4.7/2 to be the lowest uint16_t
congruent modulus 2^16 to t1
. Basically, t1
mod 2^16.
I'd say it's safe, but why not using an uint16_t without going through this misleading cast?
Types exists for communication also, not only for the sake of compilation process.
Assigning a number that cannot be represented in a signed type is implementation-defined. The next conversion however has a standard defined behaviour. So the outcome of the function is implementation defined, if that is safe or not, is a subjective matter. But portable across platforms or compilers it is not.
精彩评论