Reliable type-punning across C and C++ standards

冷暖自知 提交于 2020-01-23 06:17:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!