3 ms·
> Casting should be safe as far as I know I assume you're talking about this: long x = <whatever> double y = *(double*)&x; Nope, it is undefined beha
by mattarm 4y ago
> Casting should be safe as far as I know
I assume you're talking about this:
long x = <whatever>
double y = *(double*)&x;
Nope, it is undefined behavior, with few exceptions, even if sizeof double == sizeof long. See https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule https://stackoverflow.com/questions/98650/what-is-the-strict...
If you got rid of this rule a huge number of optimizations would be lost, since the compiler would have to assume that any memory, of any type, could change if anything at all is modified through a pointer. You'd be surprised how slow everything would be. You'd also be surprised how much code violates this and gets away with it. Time bombs waiting to happen. ;-)
memcpy(), and more generally accessing bytes through char*, are how you avoid this kind of undefined behavior. It comes up so often that C++20 added std::bit_cast for this same use: https://en.cppreference.com/w/cpp/numeric/bit_cast https://en.cppreference.com/w/cpp/numeric/bit_cast
- benmmurphy 4y agoI think he's referring to the cast: (double*)->(void*)->(double*) which should be fine. I'm guessing the original article author prefers using memcpy because there doesn't seem to be any performance cost and its correct in other situations where the alignment is wrong, or there is type aliasing. The advantage would be if you always use a safe method in a code base then you don't have to worry about proving that possibly unsafe methods are safe.
- unwind 4y agoNo, in this context (a qsort() comparison callback) I'm talking about using casts to access the values to compare. Here's how I would have written it, without memcpy(): static int cmp_double(const void *va, const void *vb) { const double a = *(const double *) va, b = *(const double *) vb; return a < b ? -1 : a > b; } I know you can't "jump types", but this doesn't, since qsort() is passing pointers to doubles and we're just getting them back. Edit: missed const:s in function body oops.