Question

In my code, I do something like the following:

double a = 3.0;
uint64_t b = static_cast<uint64_t>(a);
double c = static_cast<double>(b);

Interestingly, this works as I would expect (a == c), as long as a is positive, but if a is negative, c ends up as an arbitrarily large positive number. (It must be wrapping somewhere or something.)

My questions are:

  1. Why does this happen?
  2. Why doesn't this code break strict aliasing rules?

Note: double and uint64_t are the same size on my system.

Was it helpful?

Solution

Strict aliasing only comes into play with pointers. As in casting a double * to uint64_t * and accessing the memory through that pointer, so you don't have to worry about it here. Read the excellent answers at What is the strict aliasing rule? for more information on it.

Also as for conversion, it will try to convert the value held by your double into something representable by a uint64_t. But uint64_t is unsigned and can't represent negative values so you get undefined behavior when trying to convert a negative value (also positive valus that are too high and can't be represented). In practice you'll probably get some high positive numbers but you shouldn't rely on it.


C++ Standard (N3797) 4.9 [conv.fpint]/1 says:

A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type. [ Note: If the destination type is bool, see 4.12. — end note ]

It being well defined which Chris Dodd is refering to in his comment only holds for integral conversions, not for floating point conversions which double to uint64_t counts to.

For more info I also wrote a blog post.

OTHER TIPS

uint64_t means a 64-bit unsigned integer, so when you cast to a uint64_t, if the number is negative it overflows since an unsigned integer cannot store negative numbers.

Try it with an int64_t and it will work as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top