我正在尝试从我正在处理的一些代码中删除 c 风格的强制转换,但我担心唯一的选择。
原代码为:
WPARAM param = (WPARAM)(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
如果我使用静态转换:
WPARAM param = static_cast<WPARAM>(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
我收到错误“static_cast”:无法从“HWND”转换为“WPARAM”,因为基础类型之间没有有效的转换。这给我留下了“魔鬼的选择”:
WPARAM param = reinterpret_cast<WPARAM>(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
据我了解,如果 static_cast 是不可能的,并且这与常量无关,则 C-cast 无论如何都必须执行 reinterpret_cast,这意味着底层代码必须回退,which means this is safe (备注中的第 3 点)。但我想在更改代码之前确认这一点。
在此特定实例中此转换是否安全,我如何确认这一点?如果不能,还有什么选择?
最佳答案
这是安全的,因为WPARAM
定义为:
typedef UINT_PTR WPARAM;
和 _PTR 后缀表示该类型大到足以容纳一个指针。
而 HWND 是:
typedef HANDLE HWND;
句柄在哪里:
typedef void *HANDLE;
所以 void* 和 UINT_PTR 的大小总是相同的。如果您将它存储在 64 位应用程序中并尝试在 32 位应用程序中读取,那么您会遇到麻烦。
如果您仍然担心进行此类转换是否安全,您可以搜索 Visual Studio 源代码(在 C:\Program Files (x86)\Microsoft Visual Studio 8\文件夹中),您会发现很多行reinterpret_cast<LPARAM>(...)
和 reinterpret_cast<WPARAM>(...)
.
关于c++ - 将此 c-cast 更改为 reinterpret_cast 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21753538/