TYPE_ALIGNMENT(LARGE_INTEGER) 针对 Win10 SDK 构建时不正确
TYPE_ALIGNMENT(LARGE_INTEGER) incorrect when building against Win10 SDK
当我从 Win8.1 升级一个 C 文件时,我 运行 遇到了 Winnt.h 的 Win 10 SDK 中的这个断言问题,#includes winnt.h:
C:\Program Files (x86)\Windows
Kits\Include.0.18362.0\um\winnt.h(2487,1): error C2118: negative
subscript
#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
错误只是告诉我 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
测试代码:
#pragma pack(show)
#include "LibraryHeader.h" //somehow includes Windows.h
#pragma pack(show)
现在我得到结果:
value of pragma pack(show) == 8
value of pragma pack(show) == 4
value of pragma pack(show) == 8
所以看来我们使用的第 3 方 header 的混乱一定是造成这种情况的原因。这很奇怪,因为它针对 8.1 SDK 和 工作,因为 header 本身 明确地告诉 我们必须有 8 字节 packing/alignment 在编译器中设置。
我想 问题 归结为:W10 SDK 是否有任何方式 导致 这个假设代码没有改变并且它针对 W8.1 SDK 进行编译?或者,一直都是这样,W8.1 SDK检查失败?
Win8.1 SDK 中缺少 Win 10 SDK 问题中发布的 Winnt.h 部分,这意味着该问题一直存在但未报告。
Microsoft 提供了一种禁用此检查的方法,使用 WINDOWS_IGNORE_PACKING_MISMATCH
预处理器定义。
对于那些感兴趣的人,我在库中验证它确实是 pushing/popping 特定机器架构的打包值。我说不出为什么,但那是我愿意去的深度!
当我从 Win8.1 升级一个 C 文件时,我 运行 遇到了 Winnt.h 的 Win 10 SDK 中的这个断言问题,#includes winnt.h:
C:\Program Files (x86)\Windows Kits\Include.0.18362.0\um\winnt.h(2487,1): error C2118: negative subscript
#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
错误只是告诉我 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
测试代码:
#pragma pack(show)
#include "LibraryHeader.h" //somehow includes Windows.h
#pragma pack(show)
现在我得到结果:
value of pragma pack(show) == 8 value of pragma pack(show) == 4 value of pragma pack(show) == 8
所以看来我们使用的第 3 方 header 的混乱一定是造成这种情况的原因。这很奇怪,因为它针对 8.1 SDK 和 工作,因为 header 本身 明确地告诉 我们必须有 8 字节 packing/alignment 在编译器中设置。
我想 问题 归结为:W10 SDK 是否有任何方式 导致 这个假设代码没有改变并且它针对 W8.1 SDK 进行编译?或者,一直都是这样,W8.1 SDK检查失败?
Win8.1 SDK 中缺少 Win 10 SDK 问题中发布的 Winnt.h 部分,这意味着该问题一直存在但未报告。
Microsoft 提供了一种禁用此检查的方法,使用 WINDOWS_IGNORE_PACKING_MISMATCH
预处理器定义。
对于那些感兴趣的人,我在库中验证它确实是 pushing/popping 特定机器架构的打包值。我说不出为什么,但那是我愿意去的深度!