针对 Win10 SDK 构建时,TYPE_ALIGNMENT(LARGE_INTEGER) 不正确

Mr.*_*Boy 7 c c++ winapi visual-studio c-preprocessor

当从 Win8.1 升级 #includes winnt.h 的 C 文件时,我在 Win 10 SDK for Winnt.h 中遇到了此断言的问题:

C:\ Program Files(x86)\ Windows Kits \ 10 \ Include \ 10.0.18362.0 \ um \ winnt.h(2487,1):错误C2118:负下标

#if defined(__cplusplus) && (_MSC_VER >= 1600)
static_assert(__alignof(LARGE_INTEGER) == 8, "Windows headers require the default packing option. Changing this can lead to memory corruption."
" This diagnostic can be disabled by building with WINDOWS_IGNORE_PACKING_MISMATCH defined.");
#elif _MSC_VER >= 1300
#pragma warning(push)
#pragma warning(disable: 4116)
C_ASSERT(TYPE_ALIGNMENT(LARGE_INTEGER) == 8);    <========= LN2487
#pragma warning(pop)
#endif
#endif
Run Code Online (Sandbox Code Playgroud)

该错误只是告诉我CASSERT失败了,但我已经明确设置了 /Zp8 ,这没有什么区别。

所以我黑了Winnt.h:

// Much of the Windows SDK assumes the default packing of structs.
#if !defined(WINDOWS_IGNORE_PACKING_MISMATCH) && !defined(__midl) && !defined(MIDL_PASS) && !defined(SORTPP_PASS) && !defined(RC_INVOKED)
#if defined(__cplusplus) && (_MSC_VER >= 1600)
static_assert(__alignof(LARGE_INTEGER) == 8, "Windows headers require the default packing option. Changing this can lead to memory corruption."
    " This diagnostic can be disabled by building with WINDOWS_IGNORE_PACKING_MISMATCH defined.");
#elif _MSC_VER >= 1300
#pragma warning(push)
#pragma warning(disable: 4116)
#pragma pack(show)
C_ASSERT(TYPE_ALIGNMENT(LARGE_INTEGER) == 8);
#pragma warning(pop)
#endif
#endif
Run Code Online (Sandbox Code Playgroud)

测试代码:

#pragma pack(show)
#include "LibraryHeader.h" //somehow includes Windows.h
#pragma pack(show)
Run Code Online (Sandbox Code Playgroud)

现在我得到结果:

value of pragma pack(show) == 8
value of pragma pack(show) == 4
value of pragma pack(show) == 8
Run Code Online (Sandbox Code Playgroud)

所以看来我们使用的第三方标头的混乱一定是造成这种情况的原因。这很奇怪,因为它适用于 8.1 SDK,而且标头本身明确告诉我们必须在编译器中设置 8 字节打包/对齐。

我想问题归结为:在没有更改代码并且针对 W8.1 SDK 进行编译的情况下,W10 SDK 是否有任何方法导致此问题?或者,一直都是这样,W8.1 SDK检查失败?

Mr.*_*Boy 5

Win8.1 SDK 中缺少 Win 10 SDK 问题中发布的 Winnt.h 部分,这意味着该问题始终存在但未报告。

Microsoft 提供了一种使用预处理器定义来禁用此检查的方法WINDOWS_IGNORE_PACKING_MISMATCH

对于那些感兴趣的人,我在库中验证了它确实在推送/弹出特定机器架构的打包值。我不知道为什么,但那是我愿意去的最深的地方!