c++ - 我应该使用它还是 static_cast<void*> 然后 static_cast<myType*> 来避免重新解释?

标签 c++ casting reinterpret-cast static-cast

我看到有人建议使用 static_cast<SomeType*>(static_cast<void*>(p))而不是重新解释类型转换。

我不明白为什么这样更好,谁能解释一下?

为了便于讨论,这里有一个需要 reinterpret_cast 的示例场景:

DWORD lpNumberOfBytes;
ULONG_PTR lpCompletionKey;
LPOVERLAPPED lpOverlapped;
GetQueuedCompletionStatus(myHandle, &lpNumberOfBytes, &lpCompletionKey, &lpOverlapped, 0);
if(lpCompletionKey == myCustomHandlerKey){
    auto myObject = reinterpret_cast<MyObject*>(lpOverlapped);  //i know this is really a MyObject
}

这是我听到的建议:

auto myObject = static_cast<MyObject*>(static_cast<void*>(lpOverlapped));

编辑: 我最初的问题是 在评论部分“asdf”建议在此处使用 static_cast 而不是 reinterpret_cast http://blogs.msdn.com/b/vcblog/archive/2014/02/04/challenge-vulnerable-code.aspx 但回想起来,我的问题来自那里是无关紧要的。

最佳答案

§5.2.10 描述了 reinterpret_cast 的合法映射可以执行,并指定“不能执行其他转换”。

与您的示例相关的转换是/7:

A pointer to an object can be explicitly converted to a pointer to a different object type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast<<i>cv T2*>(static_cast<cv</i> void*>(v)) if both T1 and T2 are standard-layout types … and the alignment requirements of T2 are no stricter than those of T1. [emphasis mine]

将任何其他指针转换为对象类型的结果是“未指定的”。1

这是为什么 reinterpret_cast 的两个原因之一是危险的:它的转换仅针对指向对象类型的指针子集进行了明确定义,并且编译器通常提供有关意外误用的诊断。

第二个原因是编译器甚至不首先检查您尝试执行的映射是否合法,以及将执行许多(语义上完全不同的)映射中的哪一个。

最好是显式地告诉编译器(和读者)您要执行的预期转换是什么。也就是说,asdf 的评论并不完全正确,因为不是您可能希望通过 reinterpret_cast 执行的所有 转换相当于使用 static_cast<void*>其次是 static_cast到目标类型。


1 旁白:简而言之(并稍微简化),一个 “standard layout type”是一个没有虚函数或混合成员可见性的类型(或类型数组),它的所有成员和基类也是标准布局。 alignment类型的限制是对其可能位于内存中的地址的限制。例如,许多机器需要 double s 在可被 8 整除的地址处对齐。

关于c++ - 我应该使用它还是 static_cast<void*> 然后 static_cast<myType*> 来避免重新解释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21573712/

相关文章:

c# - 为什么不能将具有浮点值的对象强制转换为 double 值?

go - 如何在golang中将bool转换为int8

c++ - char** x = (char**) arg 是否等同于 reinterpret_cast<char**>(const_cast<void*>(arg) )?

c++ - 违反严格别名规则的类型转换

函数结束后的 C++ 变量

c++ - 不允许参数转换 - MQL5 - CArrayObj

c++ - boost async_write 问题

c++ - std::dynamic_pointer_cast 未正确向下转换

C++变量在push_back之后没有传递它的值

c++ - reinterpret_cast<> 在 sse/avx 类型上是安全的还是未定义的?