C++ type casting. When will static_cast succeed and reinterpret_cast will cause an issue?

时间:2022-09-11 12:11:16

I understand that a static_cast is a cast from one type to another that (intuitively) is a cast that could under some circumstance succeed and be meaningful in the absence of a dangerous cast. Meanwhile, a reinterpret_cast is a cast that represents an unsafe conversion that might reinterpret the bits of one value as the bits of another value.

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

Can someone describe a scenario when the code will compile, cast and static_cast will cause no issue, but with reinterpret_cast there will be an issue?

有人可以描述代码编译时的场景,演员和static_cast都不会引起任何问题,但是使用reinterpret_cast会出现问题吗?

3 个解决方案

#1


21  

This will do it:

这样做:

#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);
}

Note the differences in the two addresses.

请注意两个地址的差异。

I've built some multiple inheritance here, and have put an explicit member in the base classes, in order to circumvent possible optimisation of empty base classes to size zero.

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

See https://ideone.com/QLvBku

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

#2


16  

The simplest such case is reinterpret_cast<void*>(NULL), which may yield a non-null pointer.

最简单的情况是reinterpret_cast (NULL),这可能会产生非空指针。

By contrast, static_cast<void*>(NULL) is safe because it is required to yield a null pointer.

相比之下,static_cast (NULL)是安全的,因为它需要产生空指针。

Why? NULL is an integer constant equal to 0. static_cast requires that 0 be converted to an appropriate null pointer, but reinterpret_cast does not have this same requirement. If the internal representation of a null pointer isn't the same as that of integer zero, then the results will be different. This type of breakage would be most likely on architectures with segmented addressing.

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

#3


9  

One of such cases is multiple inheritance - static_cast does adjustment of the address (so the address of the base object pointer after the cast can be different from the derived object address, to point to the correct base class items).

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

reinterpret_cast does not do any address adjustments, so the cast to base class might use a wrong address (i.e. always returns the address of the derived object unchanged).

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

#1


21  

This will do it:

这样做:

#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);
}

Note the differences in the two addresses.

请注意两个地址的差异。

I've built some multiple inheritance here, and have put an explicit member in the base classes, in order to circumvent possible optimisation of empty base classes to size zero.

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

See https://ideone.com/QLvBku

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

#2


16  

The simplest such case is reinterpret_cast<void*>(NULL), which may yield a non-null pointer.

最简单的情况是reinterpret_cast (NULL),这可能会产生非空指针。

By contrast, static_cast<void*>(NULL) is safe because it is required to yield a null pointer.

相比之下,static_cast (NULL)是安全的,因为它需要产生空指针。

Why? NULL is an integer constant equal to 0. static_cast requires that 0 be converted to an appropriate null pointer, but reinterpret_cast does not have this same requirement. If the internal representation of a null pointer isn't the same as that of integer zero, then the results will be different. This type of breakage would be most likely on architectures with segmented addressing.

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

#3


9  

One of such cases is multiple inheritance - static_cast does adjustment of the address (so the address of the base object pointer after the cast can be different from the derived object address, to point to the correct base class items).

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

reinterpret_cast does not do any address adjustments, so the cast to base class might use a wrong address (i.e. always returns the address of the derived object unchanged).

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