在Win 10 SDK for Winnt.h中,当从Win8.1升级为C文件(其中#包括winnt.h)时,我遇到了这个断言的问题:
C:\程序文件(x86)\Windows x86错误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
错误只是告诉我CASSERT
失败了,但是我已经显式地设置了/Zp8,这并没有什么区别。
所以我黑了温特·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)
现在我得到了结果:
== 8语用包的值(显示) == 4的值(显示) == 8
所以看来,我们使用的第三方标题的混乱一定是造成这种情况的原因。这很奇怪,因为它对8.1SDK起作用,而且头本身明确地告诉我们,编译器中必须设置8字节的打包/对齐。
我想的问题归结为:如果没有改变代码并使用W8.1SDK编译W8.1SDK,W10 SDK是否会导致这种情况?或者,它一直是这样的,W8.1SDK没有检查吗?
发布于 2021-07-21 13:58:06
Winnt.h发布在Win 10 SDK问题中的部分在Win8.1SDK中缺失,这意味着问题始终存在,但没有报告。
Microsoft提供了一种使用WINDOWS_IGNORE_PACKING_MISMATCH
预处理器定义禁用此检查的方法。
对于那些感兴趣的人,我在库中验证了它确实是在为特定的机器架构推送/弹出打包值。我不知道为什么,但那是我愿意去的深度!
发布于 2022-08-16 18:29:24
我在用Visual 2017及更早版本编译良好的旧C源代码中遇到了同样的问题,但使用Windows10SDK在VisualStudio2019中发出了相同的错误。
我的问题是,解决方案中的几个项目显式地将Struct成员对齐编译器选项设置为/Zp1
,这导致了C_ASSERT
失败,导致包含文件winnt.h中“负下标”的不透明错误。
这也可能是由于在包含或处理预处理器包含或处理的包含文件winnt.h之前使用包pragma
造成的。请参阅社区中有人发布的winnt.h中的负子脚本。
我将选项从/Zp1
更改为Default
,该项目编译得很好。
也见静态断言失败,"Windows标头要求默认打包选项.“和错误Windows标头需要winnt.h上的默认打包选项
还请参阅这个,winnt.h中Windows 10.0.18362.0中的C2118错误,其中有几个帖子提到了这一点,这似乎是由于Windows10SDK中从10.0.18362.0开始的更改。
这可能意味着,我的一些依赖于具有字节成员对齐的/Zp1
的结构将创建数据错误,因此我必须跟踪这些错误,并在适当的情况下使用#pragma pack(push, 1)
和#pragma pack(pop)
。
我要加上这个答案,以防有人需要提醒我这种可能性。
https://stackoverflow.com/questions/68445163
复制相似问题