Ответ 1
Это интересно, по крайней мере, с исторической точки зрения. Я могу воспроизвести проблему с 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
. Я понятия не имею, почему это происходит - это просто эффект, который я вижу:
; 6 : for( int i = 0; i < 17; i++ )
00001 33 f6 xor esi, esi
[email protected]:
00003 8b c6 mov eax, esi
00005 c1 e0 04 shl eax, 4
; 7 : {
; 8 : int result = i * 16;
; 9 :
; 10 : if( result > 255 )
// the value `esi` is compared with in the following line should be 15!
00008 83 fe 0e cmp esi, 14 ; 0000000eH
0000b 7e 05 jle SHORT [email protected]
; 11 : {
; 12 : result = 255;
0000d b8 ff 00 00 00 mov eax, 255 ; 000000ffH
[email protected]:
; 13 : }
Обновление. Все версии VC, которые я установил раньше, чем VC 2008, имеют ту же ошибку, кроме VC6 - компиляция программы приводит к сбою компилятора VC6:
vc15-bug.cpp(10) : fatal error C1001: INTERNAL COMPILER ERROR
Итак, это ошибка, которая длилась в MSVC в той или иной форме более 10 лет!