2010-09-16 8 views

Respuesta

12

Debe usar un bloque try/catch.

Como otros ya han respondido, __try/__except es para detectar SEH (errores generados por la ventana) no para capturar excepciones generales.

Lo más importante es que __try y __catch no pueden ejecutar destructores C++ o desenrollar correctamente la pila cuando se produce una excepción.

Excepto en casos excepcionales, nunca intente atrapar excepciones de SEH.

EDIT: Bueno, yo era positivo en esto (es lo que siempre me han dicho), pero @Hans dice que aparentemente hay un interruptor de compilador que puede usar para cambiar esto. Creo que los documentos en /EHa son engañosos, o al menos incompletos, sobre lo que sucede aquí. Si alguien encuentra documentos definitivos que prueban que esto está mal, felizmente eliminaré esta respuesta.

Incluso si resulta que esto es falso, todavía se debe usar try y catch simplemente porque son estándar, mientras que __try y __except no lo son.

+0

¿Entonces no desenrolla la pila? Eso significa que probablemente sea una mala idea usar '__try' /' __except' como algo más que un sistema de informe de fallos, mientras que es común poder recuperarse de una excepción en un bloque 'try' /' catch'. –

+2

@David: Eso es correcto. '__try' y' __except' son estrictamente una API/ABI basada en C. –

+0

Los únicos buenos usos que he visto han sido lidiar con lo que equivalía a errores en Windows mismo (como lo que solía ocurrir cuando intentabas copiar un dispositivo). Podría decirse que siempre son indicativos de un lugar donde Windows debería haber atrapado la excepción para usted y la tradujo en un error. (La forma en que trabajan también es horrible, y muy específica de x86 ...) –

38

Son dos muy cosas diferentes. try/catch son las conocidas palabras clave de C++ que usted conoce. __try/__except se usa para detectar excepciones de SEH. Excepciones planteadas por Windows mismo, como DivisionByZero o AccessViolation. Está bien descrito en el MSDN Library article para ello.

También puede usarlo para capturar la excepción C++ porque aprovecha la característica Windows SEH. Sin embargo, no puede extraer el objeto de excepción arrojado así que habrá cero contexto si realmente desea que el manejador sea la excepción. Que es una locura El enfoque número uno es no tomar nunca excepciones SEH, siempre son burdas. Si necesita casar los dos, utilice _set_se_translator() para convertir la excepción SEH en una excepción de C++.

+3

+1 para MSDN ref. –

6

__try/__except está diseñado para llamar al código Win32 C que no admite excepciones pero sí utiliza un código de error estructurado/mecanismo de manejo. __try/__except traducirá errores C en un bloque de excepción similar a C++ try/catch.

Para obtener más información, vea this MSDN article.

+0

+1 para MSDN ref –

4

El estándar C++ usa bloques try/catch, por lo que recomendaría usarlos, si necesita el mecanismo de excepción "estándar", basado en la biblioteca estándar de C++.

Sin embargo, si planea utilizar el Manejo de excepciones estructuradas proporcionado a través del SDK de Windows (consulte here), utilice __try/__except.

+0

-1: El STL no tiene absolutamente nada que ver con el manejo de excepciones. –

+2

El STL tiene absolutamente algo que ver con el manejo de excepciones: std :: exception, que es la clase base recomendada para excepciones, incluso si no es obligatorio. –

+0

'std :: exception' no es una clase STL. –

1

Una vez que ha lanzado algo, ya no tiene muchas opciones sobre cómo atraparlo. Si lanza excepciones de C++ (es decir, con throw), luego use try/catch. Si lanza excepciones de Windows (es decir, con RaiseException), utilice __try/__except. Intentar mezclarlos solo agregará problemas innecesarios a su vida.

+3

Pero nunca debería arrojar excepciones de Windows porque no desenrollan la pila. –