跨 C 和 C++ 标准的可靠类型双关
Reliable type-punning across C and C++ standards
有没有一种在 C 和 C++ 中都有效的类型双关语?最好是低开销,并避免琐碎的预处理器黑客攻击。
在 C89 中,我知道我可以这样做:
unsigned int float_bits(float num) {
return *(unsigned int *)#
}
然而,这违反了 C99 的严格别名规则。所以像这样的东西可能更适合各种 C 标准:
unsigned int float_bits(float num) {
union { float f; unsigned int i; } u;
u.f = num;
return u.i;
}
但我知道这不是有效的 C++,因为联合中一次只能有一个成员处于“活动”状态。 C 和 C++ 的典型解决方案是这样的:
unsigned int float_bits(float num) {
unsigned int i;
memcpy(&i, &num, sizeof(int));
return i;
}
但是,这依赖于编译器能够优化掉对 memcpy 的调用。 memcpy 是唯一可跨 C 和 C++ 标准移植的方法吗?
unsigned int float_bits(float num) {
unsigned int i;
memcpy(&i, &num, sizeof(int));
return i;
}
除了将 i
更改为与 num
具有相同的字节外,memcpy
的调用没有任何副作用。
编译器确实可以在此处自由插入对库 memcpy
函数的调用。他们还可以免费插入100万个NOOP,一个乒乓球模拟AI训练课,并尝试搜索goldblach的猜想证明space
在某些时候,您必须假定您的编译器没有敌意。
每个体面的编译器都了解 memcpy 的作用。
有没有一种在 C 和 C++ 中都有效的类型双关语?最好是低开销,并避免琐碎的预处理器黑客攻击。
在 C89 中,我知道我可以这样做:
unsigned int float_bits(float num) {
return *(unsigned int *)#
}
然而,这违反了 C99 的严格别名规则。所以像这样的东西可能更适合各种 C 标准:
unsigned int float_bits(float num) {
union { float f; unsigned int i; } u;
u.f = num;
return u.i;
}
但我知道这不是有效的 C++,因为联合中一次只能有一个成员处于“活动”状态。 C 和 C++ 的典型解决方案是这样的:
unsigned int float_bits(float num) {
unsigned int i;
memcpy(&i, &num, sizeof(int));
return i;
}
但是,这依赖于编译器能够优化掉对 memcpy 的调用。 memcpy 是唯一可跨 C 和 C++ 标准移植的方法吗?
unsigned int float_bits(float num) {
unsigned int i;
memcpy(&i, &num, sizeof(int));
return i;
}
除了将 i
更改为与 num
具有相同的字节外,memcpy
的调用没有任何副作用。
编译器确实可以在此处自由插入对库 memcpy
函数的调用。他们还可以免费插入100万个NOOP,一个乒乓球模拟AI训练课,并尝试搜索goldblach的猜想证明space
在某些时候,您必须假定您的编译器没有敌意。
每个体面的编译器都了解 memcpy 的作用。