Мы наблюдаем странный случай, когда в VS2015 компилятор Update3 будет пропускать часть кода без видимой причины.
Мы выяснили, что
- Это происходит в VS2015 Update3 (Help | About says 14.0.25431.01 Update 3, версия cl.exe 19.00.24215.1)
- Это не происходит в VS2015 Update2 (Help | About says 14.0.25123.00 Update 2, версия cl.exe 19.00.23918)
- Это происходит только при включении оптимизации (например, в конфигурации по умолчанию)
- Случается как в x86, так и в x64
- Случается, когда фрагмент кода вставлен в новое "Консольное приложение Win32" (я имею в виду, не нужны никакие параметры командной строки)
Нам удалось свести к минимуму код виновника:
#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;
}
Для строк, которые говорят, что "Loop опущен", весь объект цикла исключается компилятором. Зачем? Насколько мне известно, не существует поведения undefined.
Разборка для первого "Loop omitted":
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
Отчет об ошибке: https://developercommunity.visualstudio.com/content/problem/71906/compiler-optimization-code-generation-bug.html