Der folgende Code generiert unterschiedliche Ergebnisse im Debug- und Release-Modus (mit 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;
}
Die Ausgabe des Debug-Modus, wie erwartet:
i: 0, result = 0
i: 1, result = 16
(...)
i:14, result = 224
i:15, result = 240
i:16, result = 255
Die Ausgabe des Freigabemodus, in dem das Ergebnis i: 15 nicht korrekt ist:
i: 0, result = 0
i: 1, result = 16
(...)
i:14, result = 224
i:15, result = 255
i:16, result = 255
Wenn Sie in Visual Studio im Release-Modus "Optimierung -> Nicht optimieren" auswählen, ist das Ausgabeergebnis korrekt. Ich möchte jedoch wissen, warum der Optimierungsprozess zu einer fehlerhaften Ausgabe führen kann.
pdate:
Wie von Mohit JainBy vorgeschlagen, druckt von:
printf("i:%2d, result = %3d, i*16=%d\n", i, result, i*16) ;
Die Ausgabe im Freigabemodus ist korrekt:
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
Das ist zumindest aus historischer Sicht interessant. Ich kann das Problem mit VC 2008 (15.00.30729.01) und VC 2010 (reproduzieren. 16.00.40219.01) (für 32-Bit x86 oder 64-Bit x64). Das Problem tritt bei keinem der Compiler auf, die ich ab VC 2012 (17.00.61030) ausprobiert habe.
Der Befehl, mit dem ich kompiliert habe: cl /Ox vc15-bug.cpp /FAsc
Da VC 2008 (und 2010) ziemlich alt ist und die Fehlerbehebung bereits seit einigen Jahren besteht, können Sie von Microsoft meines Erachtens keine andere Aktion erwarten, als einen neueren Compiler zu verwenden (obwohl vielleicht jemand einen vorschlagen kann) Problemumgehung).
Das Problem ist, dass der Test, um zu bestimmen, ob der Wert auf 255
Gesetzt werden soll, auf der Grundlage der Schleifenzahl und nicht des tatsächlichen Ergebnisses des Ausdrucks i * 16
Durchgeführt wird. Und der Compiler erhält einfach die falsche Zählung, wenn er den Wert auf 255
Zwingen soll. Ich habe keine Ahnung, warum das passiert - es ist nur der Effekt, den ich sehe:
; 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 : }
pdate: Alle Versionen von VC, die ich vor VC 2008 installiert habe, haben denselben Fehler, außer VC6 - beim Kompilieren des Programms stürzt der VC6-Compiler ab:
vc15-bug.cpp(10) : fatal error C1001: INTERNAL COMPILER ERROR
Das ist also ein Fehler, der in der einen oder anderen Form mehr als 10 Jahre in MSVC andauerte!
Vorausgesetzt, Ihre gemeldeten Fakten sind korrekt, wäre dies ein Compiler-Fehler. Überprüfen Sie die neueste Version des Compilers. Wenn der Fehler immer noch vorhanden ist, reichen Sie einen Fehlerbericht ein.