reinterpret_cast和static_cast-这里有什么区别?

时间:2018-08-22 20:55:58

标签: c++

通常认为static_cast<T*>(static_cast<void*>(a)) == reinterpret_cast<T*>(a)对于某种类型a可以强制转换为T *。在什么情况下不正确?我在下面的示例中显示了这种情况成立的情况:

#include <iostream>
#include <string>

int main() {
  std::string a = "Hello world";
  float* b = static_cast<float*>(static_cast<void *>(&a[0]));
  float* c = reinterpret_cast<float*>(&a[0]);
  std::cout << (b == c) << std::endl; // <-- This prints 1 
}

如果我的问题不清楚,请告诉我。

1 个答案:

答案 0 :(得分:0)

静态投射到另一个指针的void*或从另一个指针的reinterpret_cast进行强制转换。

使用非浮点型指针作为浮点型指针可以是UB,其中包括将一个指针值与另一个指针值进行比较是无害的。

其背后的硬件原因是,在某些平台上,浮点数必须强制对齐,而两个==上的float*可能会假定它们指向对齐的值。在至少一个平台上,char*void*都比float*占用更多的内存,因为该平台上没有字节寻址。通过存储额外的“偏移量”并在后台进行位掩码操作来模拟字节寻址。

在其他平台上,不同的地址空间完全用于不同类型的指针。我知道的一个函数和值地址空间是不同的。

考虑到此类怪癖并允许进行某些优化的标准,并未完全定义使用错误类型的指针时会发生什么。实现是免费的,可以证明它们的行为类似于您可能期望但没有强制执行的平面内存模型。

我不记得这是实现定义的(这意味着他们必须记录定义的实现或UB),还是这里的UB(这意味着编译器可以自由定义其行为,而不必这样做)。

对于T*完全有效且正确的类型(即,实际上那里存在T类型的对象),我们只有一个指向void*或{{1 }}或其他类似方法),然后在每种情况下依次选择char*

混淆问题-指向错误类型的指针-非常棘手。