El siguiente código genera resultados diferentes en el modo de depuración y en el modo de lanzamiento (con 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 salida del modo de depuración, que es como se esperaba:
i: 0, result = 0
i: 1, result = 16
(...)
i:14, result = 224
i:15, result = 240
i:16, result = 255
La salida del modo de liberación, donde i: 15 resultado no es correcto:
i: 0, result = 0
i: 1, result = 16
(...)
i:14, result = 224
i:15, result = 255
i:16, result = 255
Al elegir "Optimización -> No optimizar" en Visual Studio en modo de lanzamiento, el resultado de salida será correcto. Sin embargo, me gustaría saber por qué el proceso de optimización podría conducir a resultados erróneos.
Actualizar:
Como lo sugiere Mohit JainBy, impresiones de:
printf("i:%2d, result = %3d, i*16=%d\n", i, result, i*16) ;
La salida del modo de liberación es correcta:
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
Lorris Lin
fuente
fuente
i * 16
en la publicación, y el resultado es correcto.Respuestas:
Esto es interesante, al menos desde una perspectiva histórica. Puedo reproducir el problema con VC 2008 (15.00.30729.01) y VC 2010 (16.00.40219.01) (dirigido a 32 bits x86 o 64 bits x64). El problema no ocurre con ninguno de los compiladores que he intentado comenzar con VC 2012 (17.00.61030).
El comando que solía compilar:
cl /Ox vc15-bug.cpp /FAsc
Dado que VC 2008 (y 2010) es bastante antiguo y la solución ha estado vigente durante varios años, no creo que pueda esperar ninguna acción de Microsoft, excepto el uso de un compilador más nuevo (aunque tal vez alguien pueda sugerir una solución alternativa).
El problema es que la prueba para determinar si se debe forzar el valor
255
se realiza en función del recuento del bucle en lugar del resultado real de lai * 16
expresión. Y el compilador simplemente obtiene el recuento incorrecto de cuándo debería comenzar a forzar el valor255
. No tengo idea de por qué sucede eso, es solo el efecto que veo:Actualización : Todas las versiones de VC que instalé antes de VC 2008 tienen el mismo error, excepto VC6: la compilación del programa bloquea el compilador de VC6:
¡Entonces este es un error que duró en MSVC de una forma u otra por más de 10 años!
fuente
result > 255
a,result >= 255
se comporta correctamente. En VS2010 eso cambiacmp esi, 14
acmp esi, 16
(yjle
ajl
).Suponiendo que sus datos informados son correctos, esto sería un error del compilador. Verifique la última versión del compilador. Si el error sigue presente, envíe un informe de error.
fuente