Следующий код генерирует разные результаты в режиме отладки и в режиме выпуска (с использованием Visual Studio 2008):
int _tmain(int argc, _TCHAR* argv[])
{
for( int i = 0; i < 17; i++ )
{
int result = i * 16;
if( result > 255 )
{
result = 255;
}
printf("i:%2d, result = %3d\n", i, result) ;
}
return 0;
}
Результат режима отладки, как и ожидалось:
i: 0, result = 0
i: 1, result = 16
(...)
i:14, result = 224
i:15, result = 240
i:16, result = 255
Вывод режима выпуска, где результат i: 15 неверен:
i: 0, result = 0
i: 1, result = 16
(...)
i:14, result = 224
i:15, result = 255
i:16, result = 255
Выбрав «Оптимизация -> Не оптимизировать» в Visual Studio в режиме выпуска, выходной результат будет правильным. Однако я хотел бы знать, почему процесс оптимизации может приводить к ошибочному выводу.
Обновить:
По предложению Mohit JainBy, печатает:
printf("i:%2d, result = %3d, i*16=%d\n", i, result, i*16) ;
Выход режима выпуска правильный:
i: 0, result = 0, i*16=0
i: 1, result = 16, i*16=16
(...)
i:14, result = 224, i*16=224
i:15, result = 240, i*16=240
i:16, result = 255, i*16=256
c++
c
optimization
visual-studio-2008
compiler-bug
Лоррис Лин
источник
источник
i * 16
в сообщении, и результат правильный.Ответы:
Это интересно, по крайней мере, с исторической точки зрения. Я могу воспроизвести проблему с VC 2008 (15.00.30729.01) и VC 2010 (16.00.40219.01) (таргетинг на 32-битный x86 или 64-битный x64). Проблема не возникает ни с одним из компиляторов, которые я пробовал, начиная с VC 2012 (17.00.61030).
Команда, которую я использовал для компиляции:
cl /Ox vc15-bug.cpp /FAsc
Поскольку VC 2008 (и 2010) довольно старый и исправление существует уже несколько лет, я не думаю, что вы можете ожидать каких-либо действий от Microsoft, кроме использования более нового компилятора (хотя, возможно, кто-то может предложить обходной путь).
Проблема заключается в том, что проверка для определения необходимости принудительного
255
выполнения значения выполняется на основе количества циклов, а не фактического результатаi * 16
выражения. И компилятор просто неправильно подсчитывает, когда он должен начать принудительное присвоение значения255
. Понятия не имею, почему это происходит - это просто эффект, который я вижу:Обновление : все версии VC, которые я установил ранее, чем VC 2008, имеют одну и ту же ошибку, кроме VC6 - компиляция программы приводит к сбою компилятора VC6:
Так что это ошибка, которая в той или иной форме сохранялась в MSVC более 10 лет!
источник
result > 255
на,result >= 255
оно будет вести себя правильно. В VS2010 , что измененияcmp esi, 14
вcmp esi, 16
(иjle
кjl
).Если предположить, что сообщаемые вами факты верны, это будет ошибкой компилятора. Проверьте последнюю версию компилятора. Если ошибка все еще присутствует, отправьте отчет об ошибке.
источник