I think casting from void* back to double* is the better option here. memcpy() is overkill here since that idiom is mainly for reinterpreting data with a different type without triggering undefined behavior: https://stackoverflow.com/questions/98650/what-is-the-strict.... We're not changing the type, so why confused people with an overly powerful idiom? That said, the memcpy() idiom is common and useful enough that C++ added a specific API for it: https://en.cppreference.com/w/cpp/numeric/bit_cast.
Casting and the memcpy() idiom compile down to the same code https://godbolt.org/z/xY6W9ja69*
Are you sure this also applies to function pointers?
Not sure about the platform question, I tried building it for a Cortex-M3 (32-bit "small" ARM) but that still doesn't issue the memcpy() call. Instead it just loads pairs of words from memory then moves those into the FPU for comparison. The loads are marked with "@unaligned" but not sure what that actually means and didn't spend the time to research it now.
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...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
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.