Cra*_*ney 4 c++ casting undefined-behavior c++11 bit-cast
C++20 引入了std::bit_cast来处理相同的位,就好像它们是不同的类型一样。所以,基本上它是这样做的:
template <typename T1, typename T2>
T2 undefined_bit_cast(T1 v1) {
T1 *p1 = &v1;
T2 *p2 = (T2 *)p1; // Uh oh.
T2 v2 = *p2; // Oh no! Don't do that!
return v2;
}
Run Code Online (Sandbox Code Playgroud)
除非没有未定义的行为,允许编译器用硬盘删除方法替换此方法。
我想使用 std::bit_cast,但我坚持使用 C++11。如何正确实现我自己的custom_bit_cast
,不使用未定义的行为,而不使用实际的std::bit_cast
?
后续问题:是否有指针位转换?有一种安全的方法可以让 aT1 *
和 aT2 *
指向同一位置,并且能够从两者读取和写入,而不会出现未定义的行为?
template <class T2, class T1>
T2 cpp11_bit_cast(T1 t1) {
static_assert(sizeof(T1)==sizeof(T2), "Types must match sizes");
static_assert(std::is_pod<T1>::value, "Requires POD input");
static_assert(std::is_pod<T2>::value, "Requires POD output");
T2 t2;
std::memcpy( std::addressof(t2), std::addressof(t1), sizeof(T1) );
return t2;
}
Run Code Online (Sandbox Code Playgroud)
您可以将 pod 限制放宽到可轻松复制。
编译器非常好,上面的内容被优化为良好的汇编。
至于指针位,没有安全的方法来读取类型的对象,T1
就好像它是类型的对象,T2
其中T1
和T2
是任意的。有些情况是允许的,但范围很窄。
归档时间: |
|
查看次数: |
2864 次 |
最近记录: |