docs for ShellExecute
状态(斜体强调地雷):
返回值
类型:HINSTANCE
如果函数成功,则返回大于32的值。如果函数失败,它将返回一个错误值,该值指示故障的原因。为了与16位Windows应用程序向后兼容,返回值转换为HINSTANCE .然而,这并不是真正的HINSTANCE。只能将其转换为int,并将其与下面的32或以下错误代码进行比较。
然而,像这样服从他们:
if ((int)ShellExecuteW(...) <= 32) ...
使用MSVC 2019编译时会产生警告(32位和64位):
warning C4311: 'type cast': pointer truncation from 'HINSTANCE' to 'int'
warning C4302: 'type cast': truncation from 'HINSTANCE' to 'int'
使用reinterpret_cast<int>
会产生类似的结果。
我可以压制这一行的警告:
#pragma warning(suppress: 4311 4302)
if ((int)ShellExecuteW(...) <= 32) ...
但我一般不喜欢这样做,除非没有其他选择。因此,我的问题是:是否还有其他选择?有什么C++语法可以让我在不生成警告的情况下遵守API文档?
发布于 2021-04-14 20:08:05
HINSTANCE
是指针类型。编译器警告您,指针的大小大于int
的大小,因此在将HINSTANCE
转换为int
时将截断位。在为64位编译时会发生这种情况,其中指针为8字节,int
为4字节。
在这种特殊情况下,截断是很好的,因为值永远不会超过int
所能容纳的值。但是,如果您真的想避免这些警告,那么只需使用intptr_t
或INT_PTR
或任何类似的指针大小的整数类型,例如:
if (reinterpret_cast<intptr_t>(ShellExecuteW(...)) <= 32) {
...
}
否则,根本不使用ShellExecute()
,而是使用ShellExecuteEx()
。它返回一个成功/失败的BOOL
,并使用GetLastError()
报告失败时的标准Win32错误代码( ShellExecute()
返回的大多数错误代码都不是标准的Win32错误代码),例如:
SHELLEXECUTEINFOW info = {...};
if (!ShellExecuteExW(&info)) {
DWORD error = GetLastError();
...
}
https://stackoverflow.com/questions/67098202
复制相似问题