提醒我,尽管我使用选项{{1进行编译,但我的二进制文件将在没有SSE支持的情况下在CPU 上崩溃,异常代码为0xC000001D
(STATUS_ILLEGAL_INSTRUCTION)。 }}。而且我已经能够找到崩溃的确切位置:第一次调用 /arch:IA32
时,它将崩溃。崩溃位于 ucrtbase.dll 内部,不是我自己的代码。
现在,有趣部分是,当我使用编译器选项 _snprintf_s()
进行“完全静态”构建时,请避免显式依赖< strong> ucrtbase.dll ,生成的二进制文件就可以了!但是,一旦我将完全相同的代码编译为“共享”构建,并使用选项 /MT
,它将再次在 ucrtbase.dll 中崩溃。 >
因此,似乎 UCRT 的“静态”版本仍然可以 在CPU 上运行而无需 SSE支持,但“共享” “(DLL)版本可以 不能 。这种不一致在我看来显然是个错误!
有什么想法吗?
构建环境:
/MD
v141_xp
测试机(仅用于兼容性测试):
注意:用于设置“共享”版本的Redist DLL(/arch:IA32
+ ucrtbase.dll
)已直接从api-ms-win-*.dll
目录中复制!据我所知,这是这些DLL的最新可用版本(v10.0.17134.12)。
即使这个最小的测试程序也可以重现崩溃:
C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86
答案 0 :(得分:2)
更新:
经过更多的调试和摆弄之后,我做了一个非常有趣的观察:最新 vcredist_x86.exe
中包含的UCRT“ Redist” DLL(Microsoft Visual C ++ 2017 Redistributable安装程序),即VS2017.8(v14.15.26706)附带的版本,实际上与 latest的Redist\ucrt\DLLs\x86
目录中的UCRT“ Redist” DLLs完全不同。 Windows SDK (v10.0.17134.12):
ucrtbase.dll
v10.0.17134.12
ucrtbase.dll
:
v10.0.10586.15
实际上,我现在可以确认使用 latest Visual C ++ 2017(v14.15.26706)和 /MD
选项编译的应用程序可以在非 -SSE CPU,只要我们使用从最新 提取的“旧” ucrtbase.dll
版本vcredist_x86.exe
安装程序。
如果Windows SDK已经提供了较新的版本,我会担心使用UCRT的旧版本。但是,显然,这就是Microsoft使用Visual C ++ 2017 Redistributable安装程序进行的工作。所以,我想这就是我们应该使用的...
以防万一Microsoft的任何人正在阅读以下内容:
如果在Windows SDK的Redist\ucrt
目录中存在单独的内容,则对于软件开发人员来说,事情可能会 更少混乱和容易出错UCRT每个“化身”的子文件夹-UCRT的最新“最先进”版本和我们实际上应该重新分发的UCRT的“兼容”版本。如果 then 微软公司的某人花了三分钟来编写一个小的README文件,该文件告诉我们应该将CRT的哪一个“化身”放入Redist\ucrt\README.txt
,则几乎不可能做错了...