问题
Is there a way to type-pun that is valid in both C and C++? Preferably low overhead, and avoiding trivial preprocessor hacks.
In C89, I know I can do something like this:
unsigned int float_bits(float num) {
return *(unsigned int *)#
}
However this violates C99's strict aliasing rule. So something like this might be more portable across the various C standards:
unsigned int float_bits(float num) {
union { float f; unsigned int i; } u;
u.f = num;
return u.i;
}
But I know that this is not valid C++, because only one member of a union can be “active” at a time. The typical solution given for both C and C++ is something like this:
unsigned int float_bits(float num) {
unsigned int i;
memcpy(&i, &num, sizeof(int));
return i;
}
However, this relies on the compiler being able to optimize away the call to memcpy. Is memcpy the only method that is portable across C and C++ standards?
回答1:
unsigned int float_bits(float num) {
unsigned int i;
memcpy(&i, &num, sizeof(int));
return i;
}
there is no side effect from that call of memcpy
other than changing i
to have the same bytes as num
did.
It is true that compilers are free to insert a call to a library memcpy
function here. They are also free to insert 1 million NOOPs, a pong simulation AI training session, and try to seach the proof space for the goldblach's conjecture proof.
At some point you have to presume your compiler isn't hostile.
Every decent compiler understands what memcpy does.
来源:https://stackoverflow.com/questions/58674606/reliable-type-punning-across-c-and-c-standards