Type Punning 的真正含义是联合的应用?
what really mean by Type Punning is an application of union?
union 中类型双关的真正含义是什么?
例如`
#include <iostream>
using namespace std;
union test {
int x;
float y;
};
int main()
{
test t;
t.y = 1.5;
cout<<t.x;
return 0;
}
`
输出为 1069547520
这个值代表什么?如何预测?
类型调整意味着将一种类型的底层字节重新解释为另一种类型的字节。联合可以(误)用于此,因为所有成员共享相同的内存位置。
从非活动联合成员读取是 C++ 中的未定义行为。
It is allowed in C and GNU C++.
普通可复制 类型的正确 C++ 方法是使用 std::memcpy
:
#include <cstring>
int main()
{
std::uint32_t x = 12;
float y;
// This is OK, but the value of `y` is implementation-defined.
std::memcpy(&y,&x,sizeof(x));
// THIS IS UNDEFINED BEHAVIOUR.
y = *reinterpret_cast<float*>(&x);
static_assert(sizeof(x)==sizeof(y),"Sanity check");
}
请注意,reinterpret_cast<T*>(address)
是不够的,因为它要求 T
对象存在于 address
处,否则您将违反严格的别名规则(有一些例外)。也无需担心使用 std::memcpy
的性能下降,优化不会复制任何字节,除非需要。该调用将只是向编译器提示您确实打算这样做。
尽管上面的示例没有表现出未定义的行为,但 y
的值仍然取决于整数和浮点数的精确位表示,它们大多是实现定义的。在 C++20 中,整数需要使用 2 补码,但浮点数不需要遵守,例如IEEE 754.
union 中类型双关的真正含义是什么? 例如`
#include <iostream>
using namespace std;
union test {
int x;
float y;
};
int main()
{
test t;
t.y = 1.5;
cout<<t.x;
return 0;
}
` 输出为 1069547520
这个值代表什么?如何预测?
类型调整意味着将一种类型的底层字节重新解释为另一种类型的字节。联合可以(误)用于此,因为所有成员共享相同的内存位置。
从非活动联合成员读取是 C++ 中的未定义行为。 It is allowed in C and GNU C++.
普通可复制 类型的正确 C++ 方法是使用 std::memcpy
:
#include <cstring>
int main()
{
std::uint32_t x = 12;
float y;
// This is OK, but the value of `y` is implementation-defined.
std::memcpy(&y,&x,sizeof(x));
// THIS IS UNDEFINED BEHAVIOUR.
y = *reinterpret_cast<float*>(&x);
static_assert(sizeof(x)==sizeof(y),"Sanity check");
}
请注意,reinterpret_cast<T*>(address)
是不够的,因为它要求 T
对象存在于 address
处,否则您将违反严格的别名规则(有一些例外)。也无需担心使用 std::memcpy
的性能下降,优化不会复制任何字节,除非需要。该调用将只是向编译器提示您确实打算这样做。
尽管上面的示例没有表现出未定义的行为,但 y
的值仍然取决于整数和浮点数的精确位表示,它们大多是实现定义的。在 C++20 中,整数需要使用 2 补码,但浮点数不需要遵守,例如IEEE 754.