C++类型转换.static_cast何时成功并且reinterpret_cast会导致问题?

Nar*_*yan 24 c++ casting

我理解a static_cast是一种从一种类型到另一种类型的演员,(直觉上)是一种演员,在某些情况下可以成功并且在没有危险演员的情况下有意义.同时,a reinterpret_cast是一个表示不安全转换的转换,它可能将一个值的位重新解释为另一个值的位.

当代码编译,转换并且static_cast不会引起任何问题时,有人可以描述一个场景,但是reinterpret_cast会出现问题吗?

Bat*_*eba 21

这样做:

#include <iostream>
using namespace std;

struct C{int n;};
struct A{int n;};
struct B : A, C{};

int main()
{
    B b;
    B* pb = &b;
    cout << static_cast<C*>(pb) << "\n";
    cout << reinterpret_cast<C*>(pb);
}
Run Code Online (Sandbox Code Playgroud)

请注意两个地址的差异.

我在这里构建了一些多继承,并在基类中放置了一个显式成员,以避免将空基类的可能优化大小为零.

请参阅https://ideone.com/QLvBku

  • 注意:如果没有多重继承,没有虚方法的基类和带有虚方法的派生类将生成"v-ptr"大小的偏移(加上潜在的填充). (4认同)

Tob*_*ght 16

最简单的情况是reinterpret_cast<void*>(NULL),它可能产生一个非空指针.

相比之下,static_cast<void*>(NULL)是安全的,因为它需要产生一个空指针.

为什么?NULL是一个等于0的整数常量.static_cast要求将0转换为适当的空指针,但reinterpret_cast不具有相同的要求.如果空指针的内部表示与整数零的内部表示不同,则结果将不同.这种类型的破坏最有可能发生在具有分段寻址的架构上.

  • `reinterpret_cast`的CPP参考说"*空指针常量`NULL`或整数零不保证产生目标类型的空指针值;`static_cast`或隐式转换应该用于此目的.*" (2认同)

axa*_*lis 9

其中一种情况是多重继承 - static_cast调整地址(因此,强制转换后基础对象指针的地址可以与派生对象地址不同,指向正确的基类项).

reinterpret_cast 不执行任何地址调整,因此强制转换为基类可能使用错误的地址(即始终返回派生对象的地址不变).