将 ShellExecute return (HINSTANCE) 转换为 int 时避免 MSVC 警告

Avoid MSVC warning when casting ShellExecute return (HINSTANCE) to int

docs for ShellExecute 状态(斜体强调我的):

Return value

Type: HINSTANCE

If the function succeeds, it returns a value greater than 32. If the function fails, it returns an error value that indicates the cause of the failure. The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. It can be cast only to an int and compared to either 32 or the following error codes below.

然而,像这样服从他们:

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 文档?

HINSTANCE是指针类型。编译器警告您指针的大小大于 int 的大小,因此在将 HINSTANCE 转换为 int 期间将截断位。当您为 64 位编译时会发生这种情况,其中指针为 8 个字节,int 为 4 个字节。

在这种特殊情况下,截断没问题,因为值永远不会超过 int 可以容纳的值。但是,如果你真的想避免警告,那么只需使用 intptr_tINT_PTR 或任何其他类似的指针大小的整数类型,例如:

if (reinterpret_cast<intptr_t>(ShellExecuteW(...)) <= 32) {
    ...
}

否则,根本不使用 ShellExecute(),而是使用 ShellExecuteEx()。它 returns 一个 BOOL for success/failure,并使用 GetLastError() 在失败时报告标准的 Win32 错误代码(大多数 ShellExecute() 返回的错误代码不是标准的Win32 错误代码),例如:

SHELLEXECUTEINFOW info = {...};

if (!ShellExecuteExW(&info)) {
    DWORD error = GetLastError();
    ...
}