please delete me
please delete me

Reputation: 721

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!

Upvotes: 2

Views: 3428

Answers (3)

Matthew Flaschen
Matthew Flaschen

Reputation: 284786

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.

Upvotes: 5

daramarak
daramarak

Reputation: 6145

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.

Upvotes: 0

Simone
Simone

Reputation: 11797

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.

Upvotes: 1

Related Questions