reinterpret_cast <char * =“”> reinterpret_cast的唯一有效用途是什么?

时间:2016-05-12 04:51:27

标签: c++ strict-aliasing

我最近了解到C ++标准包含&#34;严格别名规则&#34;,禁止通过不同类型的变量引用相同的内存位置。

但是,该标准允许char类型合法地为任何其他类型设置别名。这是否意味着reinterpret_cast可以合法地仅用于投射到char *char &类型?

我认为严格别名允许在继承层次结构中的类型之间进行转换,但我认为这些情况倾向于使用dynamic_cast&lt;&gt;?

谢谢

3 个答案:

答案 0 :(得分:9)

reinterpret_cast有许多不同的用法。 cppreference page列出了11种不同的案例。

我想您只是询问案例5和案例6:将T *投射到U *,并将T投射到U &

在这些情况下,只要没有对齐违规,演员表就是合法的。只有在读取或写入结果表达式时才会出现严格的别名问题。

您的第一段中的严格别名规则摘要过于简单化,一般来说U有几种合法类型。同一个cppreference页面给出了一个项目符号列表;您可以在C ++标准草案中阅读规则的确切文本。

答案 1 :(得分:6)

reinterpret_cast还有其他用途。

指向整数类型的指针

是的,有时候想要将指针的值存储在整数类型中。

使用C ++样式转换执行此操作的唯一方法是使用reinterpret_cast

示例:

auto pointerValue = reinterpret_cast<std::uintptr_t>(pointer);

将对象存储在原始内存块

有时您希望将数据存储在堆栈中,但稍后会对其进行初始化。使用动态分配和指针不会使用堆栈。 std::aligned_storage作为原始的,对齐的内存块做得很好。

struct MyStruct {
    int n;
    std::string s;
};

// allocated on automatic storage
std::aligned_storage<sizeof(MyStruct), alignof(MyStruct)>::type storage;

// actually initialize the object
new (&storage) MyStruct;

// using the object
reinterpret_cast<MyStruct*>(&storage)->n = 42;

我确定还有很多其他用途,我不知道,但这些是我已经使用过的。

答案 2 :(得分:5)

您还可以使用reinterpret_cast将指针类型强制转换为整数类型:

char* ptr = /* ... */
uintptr_t ptrInt = reinterpret_cast<uintptr_t>(ptr);

您获取的特定整数值不能跨平台移植,但这是一个安全且定义明确的操作。