2010-09-24 11 views

Respuesta

19

que en realidad tienen tres mecanismos:

  • C++ excepciones, implementado por el compilador (try/catch)
  • estructurado de excepciones de manipulación (SEH), proporcionado por Windows (__try/__except)
  • MFC macros de excepción (TRY, CATCH - construidas sobre excepciones de SEH/C++ - vea también el comentario de TheUndeadFish)

Las excepciones de C++ generalmente garantizan la limpieza automática durante el desenrollado de la pila (es decir, se ejecutan destructores de objetos locales), los otros mecanismos no funcionan.

Las excepciones de C++ solo se producen cuando se lanzan explícitamente. Se pueden producir excepciones estructuradas para muchas operaciones, p. debido a un comportamiento indefinido, pasando punteros no válidos a las API, desmontando el almacén de respaldo de un archivo mapeado en memoria, y muchos más.

MFC presentó las macros de excepciones para admitir excepciones incluso si los compiladores no las implementaron.

+0

¿Por curiosidad, MFC alguna vez intentaron trabajar en cualquier compilador que no sea VC++? –

+2

Las excepciones de C++ no son necesarias para garantizar la limpieza. Compila con/EHa. –

+0

MFC funcionó en Watcom C/C++ 10. De alguna manera. Sin los hechiceros y esas cosas. – peterchen

6

Una excepción de C++ es una característica del lenguaje de programación C++. Una excepción estructurada es un concepto diferente del sistema operativo Windows. Estos dos utilizan una sintaxis similar, pero son técnicamente diferentes. Las excepciones estructuradas de Windows no solo se pueden usar con C++ sino también, p. Ej. con C.

A veces una solución para unificar el manejo de ambos: en una aplicación de Windows puede proporcionar una función de controlador, que atrapa todas las excepciones estructuradas y arroja una excepción C++ (definida por usted).

4

Ambos proporcionan mecanismos para el desenrollado de la pila cuando se producen errores.

Las excepciones estructuradas son proporcionadas por Windows, con soporte del kernel. Son creados por Windows si haces cosas como acceder a una ubicación de memoria no válida. También se usan para admitir funciones como el crecimiento automático de la pila. Se usan con bastante poca frecuencia por sí mismos, pero a menudo se crean excepciones de lenguaje en C++, .NET e idiomas similares. Utiliza palabras clave especiales como __try y __catch para tratar estas excepciones. Sin embargo, lidiar con ellos es comparativamente difícil y propenso a errores, ya que puede romper características como la expansión automática de la pila, así como las posibles excepciones al lenguaje C++.

Las excepciones de C++ están especificadas por el lenguaje C++. Los tipos de datos que se arrojan y atrapan son objetos C++ (incluida la posibilidad de tipos primitivos). El compilador y el tiempo de ejecución implementa estos sobre el mecanismo de excepción estructurado subyacente. Esto es lo que obtiene si usa las palabras clave try, catch y throw del lenguaje C++.

Las excepciones SEH tienen más características que las excepciones C++, como la reanudación de soporte, y los llamados manejadores "vectorizados" (que reciben notificaciones de excepciones, pero no necesariamente previenen el desenrollado de la pila), pero a menos que sepa específicamente que desea úsalos, los evitaría. Probablemente el uso más común de ellos es escribir un volcado de emergencia usando MiniDumpWriteDump si su programa hace algo ilegal o indefinido.

1

Las excepciones de C++ funcionarán a través de la plataforma. Desafortunadamente, SEH restringirá severamente la portabilidad (excepto que puede encontrarse en diferentes versiones de Windows).

también SEH parece capturar un montón de excepciones nativas de Windows (como Violación de Acceso, un identificador no válido se especificó), etc.

7

Es un detalle de implementación pesado, pero en Windows de C++ excepción es también una excepción SEH. El código de excepción es 0xE04D5343 (últimos tres bytes = 'MSC'). Y todo el soporte SEH regular se usa para desenrollar la pila, obtener código de limpieza automática para que se ejecute y filtrar la excepción para que se seleccione la cláusula de captura adecuada. Obtener el objeto de excepción lanzada en la expresión de filtro es la instalación de tuberías añadida por el CRT más allá de lo que proporciona SEH. SEH también admite una cláusula __finally, pero eso no se usa en C++ estándar.

Otro detalle de la implementación es la configuración del compilador/EH. El valor predeterminado (/ EHsc) permite al compilador optimizar el código que se genera y suprimir los filtros de excepción que se necesitan para ejecutar la limpieza automática. Si puede ver que ninguno de los códigos C++ emitidos puede arrojar una excepción. Esto es, sobre todo, una optimización del espacio, una pequeña optimización de tiempo para el código x86 pero no para el código x64. Para obtener la limpieza automática de las excepciones SEH, debe compilar con/EHa para que esta optimización se suprima.

Una buena estrategia para unir excepciones de C++ con SEH es usar _set_se_translator() para que pueda traducir una excepción de SEH a una excepción de C++. Aunque a menudo no es prudente detectar excepciones de SEH, casi siempre son desagradables.

+0

¿__try/__ except blocks capturará todas las excepciones de SEH y todas las excepciones de C++? – Alexandru

+0

También es importante tener en cuenta que _set_se_translator() solo se llama una vez para cada invocación de función en la pila que tiene bloques de prueba, según MSDN, y debe establecerse por subproceso. – Alexandru

Cuestiones relacionadas