首页 > 解决方案 > 在遵守严格的别名规则的同时使用 reinterpret_cast

问题描述

我知道这段代码会undefined behaviour由于违反严格的别名规则而导致,因为我们指向具有类型的相同内存位置intfloat取消引用它,在编译器优化发生后代码可能会中断:

int main(){
 int a = 5;
 float f = *reinterpret_cast<float*>(&a);

 return (int) f;
}

但是这个片段怎么样?

#include <iostream>

int main(){
 intptr_t p = 1234; // let's assume this is a valid address in memory.
 float f = *reinterpret_cast<float*>(p);

 return (int) f;
}

在上面,如果我们假设p是一个有效的内存地址(不会导致段错误),它是否仍然有 UB 并打破严格的别名规则?没有其他代码指向该内存块。

编辑

我的第二个例子可以这样写bit_cast

intptr_t p = 1234; // let's assume this is a valid address in memory.
float f = *std::bit_cast<float*>(p);

标签: c++

解决方案


是的,它仍然会打破严格的别名规则,因为您将尝试取消引用指向 的指针float,但float对象从未存在于该地址。

幸运的是,在 C++ 20 中,您可以std::bit_cast用于此目的。在 C++20 之前,您可以直接转换 :),因为即使这是 UB,也没有理智的编译器会产生与您期望的结果不同的结果,因为这种技术无处不在。


推荐阅读