【发布时间】:2017-11-25 22:36:57
【问题描述】:
我们观察到一个奇怪的情况,在 VS2015 Update3 编译器会无缘无故地省略部分代码。
我们发现
- 这发生在 VS2015 Update3 中(帮助|关于说 14.0.25431.01 Update 3,cl.exe 版本 19.00.24215.1)
- 这在 VS2015 Update2 中不会发生(帮助|关于说 14.0.25123.00 Update 2,cl.exe 版本 19.00.23918)
- 只有在开启优化时才会发生这种情况(例如,在默认发布配置中)
- 在 x86 和 x64 中都发生
- 将代码 sn-p 插入全新的“Win32 控制台应用程序”时发生(我的意思是,不需要花哨的命令行选项)
我们设法最小化了这个 sn-p 的罪魁祸首代码:
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
int _tmain(int, _TCHAR*[])
{
volatile int someVar = 1;
const int indexOffset = someVar ? 0 : 1; // Loop omitted
// const int indexOffset = !someVar; // Loop omitted
// const int indexOffset = 0; // Good
// const int indexOffset = 1; // Good
// const int indexOffset = someVar; // Good
// const int indexOffset = someVar + 1; // Good
for (int i = 1 - indexOffset; i < 2 - indexOffset; ++i)
{
printf("Test passed\n");
}
return 0;
}
对于说“省略循环”的行,编译器会省略整个循环体。为什么?据我所知,不涉及未定义的行为。
第一个“省略循环”的反汇编:
int _tmain(int, _TCHAR*[])
{
01151010 push ebp
01151011 mov ebp,esp
01151013 push ecx
volatile int someVar = 1;
01151014 mov dword ptr [ebp-4],1
const int indexOffset = someVar ? 0 : 1; // Loop omitted
0115101B mov eax,dword ptr [someVar]
// const int indexOffset = !someVar; // Loop omitted
// const int indexOffset = 0; // Good
// const int indexOffset = 1; // Good
// const int indexOffset = someVar; // Good
// const int indexOffset = someVar + 1; // Good
for (int i = 1 - indexOffset; i < 2 - indexOffset; ++i)
{
printf("Test passed\n");
}
system("pause");
0115101E push offset string "pause" (011520F8h)
01151023 call dword ptr [__imp__system (0115205Ch)]
01151029 add esp,4
return 0;
0115102C xor eax,eax
}
0115102E mov esp,ebp
01151030 pop ebp
01151031 ret
测试项目:http://dropmefiles.com/S7mwT
在线试用!
- 转到http://webcompiler.cloudapp.net/
- 将示例代码放入编辑器
- 将
/O2放入Additional compiler flags - 检查
Run executable after compilation
【问题讨论】:
-
能否给出编译代码的命令行?我想试试最新的 MSVC 版本。也就是说,它绝对看起来像一个错误。您似乎也缺少包含。
-
“不工作”意味着没有打印消息,或者断点没有触发? FWIW,第一个“不起作用”情况的
main汇编代码是什么? -
您缺少一些包含。
tchar.h、windows.h和cstdio。这绝对是一个编译器错误 - 它适用于 MSVC x64 19.10.25019 (VS15 RTM) 和 19.11.25325 (VS15.3 Preview)。您应该升级您的编译器 - 不支持 MSVC 19.0。 -
@Codeguard -- 您正在查看 Visual Studio 本身的版本,而不是编译器版本。要获取编译器版本,请在命令行输入
cl /?。 -
很多人声称发现了编译器错误,而实际上它是他们自己代码中的错误。看到一个可能是编译器错误的,真是令人耳目一新!
标签: c++ visual-studio-2015 compiler-errors compiler-optimization