我最近了解到C ++标准包含"严格别名规则",禁止通过不同类型的变量引用相同的内存位置。
但是,该标准允许char
类型合法地为任何其他类型设置别名。这是否意味着reinterpret_cast
可以合法地仅用于投射到char *
或char &
类型?
我认为严格别名允许在继承层次结构中的类型之间进行转换,但我认为这些情况倾向于使用dynamic_cast<>?
谢谢
答案 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);
您获取的特定整数值不能跨平台移植,但这是一个安全且定义明确的操作。