para - Visual Studio 2015 Update 3-¿Error del compilador C++?
visual studio code iostream not found (1)
Observamos un extraño caso donde en VS2015 Update3 el compilador omitirá parte del código sin ninguna razón obvia.
Descubrimos que
- Esto sucede en VS2015 Update3 (Help | About says 14.0.25431.01 Update 3, cl.exe version 19.00.24215.1)
- Esto no ocurre en VS2015 Update2 (Help | About says 14.0.25123.00 Update 2, cl.exe version 19.00.23918)
- Esto ocurre solo cuando la optimización está activada (por ejemplo, en la configuración de versión predeterminada)
- Sucede en x86 y x64
- Ocurre cuando el fragmento de código se inserta en la nueva "Aplicación de consola Win32" (es decir, no se requieren opciones de línea de comando sofisticadas)
Logramos minimizar el código culpable de este fragmento:
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
int _tmain(int, _TCHAR*[])
{
volatile int someVar = 1;
const int indexOffset = someVar ? 0 : 1; // Loop omitted
// const int indexOffset = !someVar; // Loop omitted
// const int indexOffset = 0; // Good
// const int indexOffset = 1; // Good
// const int indexOffset = someVar; // Good
// const int indexOffset = someVar + 1; // Good
for (int i = 1 - indexOffset; i < 2 - indexOffset; ++i)
{
printf("Test passed/n");
}
return 0;
}
Para las líneas que dicen "Loop omitido", el compilador omite todo el cuerpo del ciclo. ¿Por qué? Que yo sepa, no hay un comportamiento indefinido involucrado.
Desmontaje para el primer "Loop omitido":
int _tmain(int, _TCHAR*[])
{
01151010 push ebp
01151011 mov ebp,esp
01151013 push ecx
volatile int someVar = 1;
01151014 mov dword ptr [ebp-4],1
const int indexOffset = someVar ? 0 : 1; // Loop omitted
0115101B mov eax,dword ptr [someVar]
// const int indexOffset = !someVar; // Loop omitted
// const int indexOffset = 0; // Good
// const int indexOffset = 1; // Good
// const int indexOffset = someVar; // Good
// const int indexOffset = someVar + 1; // Good
for (int i = 1 - indexOffset; i < 2 - indexOffset; ++i)
{
printf("Test passed/n");
}
system("pause");
0115101E push offset string "pause" (011520F8h)
01151023 call dword ptr [__imp__system (0115205Ch)]
01151029 add esp,4
return 0;
0115102C xor eax,eax
}
0115102E mov esp,ebp
01151030 pop ebp
01151031 ret
Proyecto de prueba: http://dropmefiles.com/S7mwT
¡Pruébalo en línea!
- Vaya a http://webcompiler.cloudapp.net/
- Ponga código de muestra en el editor
- Poner
/O2
enAdditional compiler flags
- Comprobar
Run executable after compilation
Informe de error: https://developercommunity.visualstudio.com/content/problem/71906/compiler-optimization-code-generation-bug.html
Sí, es un error. Específicamente, es un error en el nuevo optimizador de SSA introducido en VS2015 Actualización 3. La opción de línea de comando no documentada -d2SSAOptimizer-
le dice al compilador que use el viejo optimizador, lo que hace que el error no se manifieste .
FYI, puedes minimizar tu repro para:
int main()
{
volatile int someVar = 1;
const int indexOffset = someVar ? 0 : 1;
for (int i = 1 - indexOffset; i < 2 - indexOffset; ++i)
{
return 0;
}
return 1;
}
lo que ayudará a los desarrolladores del compilador a localizar el problema más rápidamente.
Adición de Codeguard (decidí que la respuesta de Casey debería ser LA respuesta): recibí una respuesta de Microsoft (Gratian Lup, autor de la publicación de blog Presentando un nuevo y avanzado optimizador de código de Visual C ++ ):
Sí, esto es de hecho un error en el SSA Optimizer en sí mismo; por lo general, la mayoría de los errores reportados como pertenecientes al nuevo optimizador se encuentran en otras partes, a veces expuestas ahora después de 20 años.
Está en una pequeña opción. que intenta eliminar una comparación que se parece a (a - Const1) CMP (a - Const2), si no hay desbordamiento. El problema es que su código tiene (1 - indexOffset) CMP (2 - indexOffset) y la resta no es conmutativa, por supuesto - pero el código del optimizador lo ignora y maneja (1 - indexOffset) como si fuera (indexOffset - 1).
Se lanzará una solución para este problema en la próxima actualización más grande para VS2017. Hasta entonces, deshabilitar el SSA Optimizer sería una solución decente. Deshabilitar las optimizaciones solo para esta función puede ser un mejor enfoque si no desacelera demasiado las cosas. Esto se puede hacer con #pragma optimize ("", off): https://msdn.microsoft.com/en-us/library/chh3fb0k.aspx