Excepción de C++ "Salta" la cláusula Try-Catch en MSVC x64
windows exception (3)
Estoy escribiendo un programa en C ++. El programa ha funcionado bien para Win32 (x86), y recientemente he intentado compilarlo de forma nativa para x64. Por supuesto, las cosas no funcionaron de inmediato.
Después de depurar el problema, logré reproducirlo con este simple fragmento de código:
class MyException { };
int main()
{
try {
for (;;) {
try {
std::cout << "Throwing" << std::endl;
throw MyException();
if (1 == 0) {
continue;
}
} catch (const MyException&) {
std::cout << "Catch 1" << std::endl;
}
}
} catch (const MyException&) {
std::cout << "Catch 2" << std::endl;
}
std::cout << "Done" << std::endl;
return 0;
}
(Explicaré la cláusula if (1==0)
pronto)
Al compilar este código utilizando MSVC para x86 (he usado 2010), el resultado es el esperado:
Throwing
Catch 1
Throwing
Catch 1
Throwing
Catch 1
Throwing
Catch 1
...
Y así sucesivamente, en un bucle infinito.
Sin embargo, compilar este código para x64 da como resultado:
Throwing
Catch 2
Done
¡La excepción omite completamente la cláusula de captura interna!
Esto solo ocurre cuando existe la cláusula if (1 ==0)
en mi código. Cuando lo quito, la excepción queda atrapada en "Captura 1" como se esperaba.
He intentado usar otros compiladores:
- Este error también ocurre en VS 2012.
- MinGW y MinGW-w64 funcionan como se espera.
Mi pregunta: ¿es este un error de MSVC o es un comportamiento indefinido en C ++? Si esto realmente es un error de MSVC, me encantaría escuchar alguna idea sobre la causa.
Gracias.
Este error puede tener algo que ver con la optimización del compilador: es interesante que el vinculador se bloquee en la compilación de la versión (cuando la optimización completa estaría teóricamente activada).
¿Su compilación de depuración tiene la optimización completamente deshabilitada (/ Od)?
La Ayuda de Visual Studio también contiene una declaración (bajo "Mejores prácticas de optimización") que desalienta los bloques try / catch en el código de 64 bits.
Si desactivas la optimización en la versión de lanzamiento, el enlazador no se bloquea. Tampoco se bloqueará (pero reproducirá el mal comportamiento) si elimina solo la instrucción "continue".
if (1==0) {
//continue;
}
Pruebe el interruptor / FAs switch:
http://msdn.microsoft.com/en-us/library/367y26c6%28v=vs.80%29.ASPX
En algún lugar del "archivo de salida adicional" en su "configuración del compilador". (Asegúrate de que todas las otras configuraciones sean las mismas)
Luego, haz una diferencia entre ambas salidas. publicar la diferencia aquí. Estoy seguro de que algunas personas podrán decirle por qué y cómo, y tal vez algunas configuraciones del compilador o solución de código.
este es un viejo problema conocido, después de desenterrar esto es lo que descubrimos hace algún tiempo.