c++ - En mode de publication, le comportement du code n'est pas celui attendu




1 Answers

C'est intéressant, du moins d'un point de vue historique. Je peux reproduire le problème avec VC 2008 (15.00.30729.01) et VC 2010 (16.00.40219.01) (ciblant 32 bits x86 ou 64 bits x64). Le problème ne se produit avec aucun des compilateurs que j'ai essayé de commencer avec VC 2012 (17.00.61030).

La commande que j'ai utilisée pour compiler: cl /Ox vc15-bug.cpp /FAsc

Puisque VC 2008 (et 2010) est plutôt ancien et que le correctif existe depuis plusieurs années maintenant, je ne pense pas que vous puissiez espérer une action de Microsoft, sauf pour utiliser un compilateur plus récent (bien que quelqu'un puisse suggérer une solution de contournement).

Le problème est que le test pour déterminer si la valeur doit être forcée à 255 est effectué en fonction du nombre de boucles plutôt que du résultat réel de l'expression i * 16 . Et le compilateur obtient simplement le nombre faux pour quand il devrait commencer à forcer la valeur à 255 . Je ne sais pas pourquoi cela arrive - c'est juste l'effet que je vois:

; 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   :        }

Mise à jour : Toutes les versions de VC que j'ai installées plus tôt que VC 2008 ont le même bug, sauf VC6 - compiler le programme plante le compilateur VC6:

vc15-bug.cpp(10) : fatal error C1001: INTERNAL COMPILER ERROR

Donc, c'est un bug qui a duré dans MSVC sous une forme ou une autre pendant plus de 10 ans!

Le code suivant génère des résultats différents en mode débogage et en mode de publication (à l'aide de 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;
}

La sortie du mode débogage, qui est comme prévu:

i: 0, result =   0
i: 1, result =  16
(...)
i:14, result = 224
i:15, result = 240
i:16, result = 255

La sortie du mode release, où i: 15 résultat n'est pas correct:

i: 0, result =   0
i: 1, result =  16
(...)
i:14, result = 224
i:15, result = 255
i:16, result = 255

En choisissant "Optimisation -> Ne pas optimiser" dans Visual Studio en mode de validation, le résultat de sortie sera correct. Cependant, je voudrais savoir pourquoi le processus d'optimisation pourrait conduire à une sortie erronée.

Mettre à jour:

Comme suggéré par Mohit JainBy, estampes par:

printf("i:%2d, result = %3d, i*16=%d\n", i, result, i*16) ;

La sortie du mode de libération est correcte:

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



Related