usar - try catch finally c++
C++,__try y try/catch/finally (3)
En Windows, las excepciones son compatibles a nivel del sistema operativo. Llamado Manejo de excepciones estructuradas (SEH), son el equivalente aproximado a las señales de Unix. Los compiladores que generan código para Windows normalmente aprovechan esto, usan la infraestructura SEH para implementar excepciones de C ++.
De acuerdo con el estándar de C ++, las palabras clave de arrojar y atrapar solo arrojan y atrapan excepciones de C ++. El código de excepción SEH correspondiente para el compilador MSVC es 0xe06d7343. Los últimos 3 bytes son el código ASCII para "msc".
Unificarlo con el soporte del sistema operativo también significa que se invocarán destructores C ++ durante el desenrollado de la pila para una excepción SEH. El código que desenrolla está dentro de Windows y trata el SEH elevado por un lanzamiento exactamente de la misma manera que cualquier SEH. Sin embargo, el compilador de Microsoft tiene una optimización que intenta evitar generar el código requerido que asegura que se invoquen destructores en todos los casos. Si puede probar que no hay instrucción de lanzamiento dentro del bloque de alcance que controla la duración del objeto, entonces omite el código de registro. Esto no es compatible con excepciones ASH asíncronas, debe usar la opción de compilación / EHa para suprimir esta optimización si tiene la intención de detectar excepciones de SEH.
Hay muchos tipos de excepciones SEH. Los que pueden ser generados por el sistema operativo se enumeran en el archivo de encabezado ntstatus.h SDK. Además, puede interoperar con código que usa SEH para implementar su propio manejo de excepciones, ellos usarán su propio código de excepción. Al igual que .NET, las excepciones administradas usan el código de excepción 0xe0434f4d ("com").
Para detectar excepciones SEH en un programa C ++, debe usar la palabra clave __try no estándar. La palabra clave __except es análoga a la palabra clave captura C ++. Tiene más capacidades, usted especifica una expresión de filtro de excepción que determina si una excepción activa debe capturarse o no. Todo es posible, pero normalmente solo observa la información de excepción aprobada para ver si está interesado en manejarla. La palabra clave __finally le permite escribir el código que se ejecuta después de que se maneja la excepción. No hay equivalente para eso en C ++, pero no es raro en otros idiomas.
Todo esto está bastante poco documentado, como se señala en los comentarios. La prueba está en el pudín. Aquí hay un programa de ejemplo con el que puedes jugar. Demuestra cómo las excepciones de SEH aún permiten que se invoquen destructores de C ++, siempre que compile con / EHa y cómo las excepciones de C ++ se implementan sobre SEH. Se requiere el compilador MSVC, ejecute Ctrl + F5 para evitar que el depurador sea útil:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
// NOTE: the value of the C/C++, Code Generation, Enable C++ Exceptions setting in important
// Try it both with /EHsc (the default) and /EHa to see the difference
class Example {
public:
~Example() { std::cout << "destructed" << std::endl; }
};
int filterException(int code, PEXCEPTION_POINTERS ex) {
std::cout << "Filtering " << std::hex << code << std::endl;
return EXCEPTION_EXECUTE_HANDLER;
}
void testProcessorFault() {
Example e;
int* p = 0;
*p = 42;
}
void testCppException() {
Example e;
throw 42;
}
int main()
{
__try {
testProcessorFault();
}
__except(filterException(GetExceptionCode(), GetExceptionInformation())) {
std::cout << "caught" << std::endl;
}
__try {
testCppException();
}
__except(filterException(GetExceptionCode(), GetExceptionInformation())) {
std::cout << "caught" << std::endl;
}
return 0;
}
Salida:
Filtering c0000005
destructed
caught
Filtering e06d7363
destructed
caught
Me pregunto un poco sobre C ++ try / catch / finally blocks. He visto estos comandos con dos guiones bajos como __try. Pero los proyectos de MVSC 2010 también se ejecutan sin los guiones bajos. Entonces, ¿cuándo necesitas estos caracteres de subrayado?
__try/__except
es específico de Microsoft. Si quiere que su código sea compilable con otros compiladores (por ejemplo, el +++) (o) en otro sistema operativo, evite usarlos, y quédese con las declaraciones try/catch
estándar try/catch
__try
/ __except
es para detectar SEH (errores generados por Windows) no para detectar excepciones generales.
try
/ catch
es lo que el estándar C ++ especifica para manejar excepciones generales de C ++.
Para el código estándar de C ++ que escriba, siempre debe usar try
/ catch
y no __try
/ __except
Además, finally
no es la construcción especificada estándar de C ++. Funciona para usted porque es una extensión del compilador de Microsoft .