2010-12-10 8 views
14

Si estoy creando un nuevo proyecto en C++ no administrado, Visual Studio 2008 o superior, ¿con qué modelo de manejo de excepciones quiero ir?Código no administrado de Visual C++: ¿Utiliza/EHa o/EHsc para las excepciones de C++?

Entiendo que la opción/EHa da como resultado un código menos eficiente y también detecta excepciones SEH, ¿no?

Así que me he estado desviando de esa opción y normalmente voy con/EHsc, de modo que solo estoy atrapando excepciones de C++ que realmente se lanzan y no detectan violaciones de acceso y otras ejecuciones estructuradas, en catch (...) manejadores. Si hay una infracción de acceso en mi código, no quiero que esté enmascarado por un catch (...) {}.

Cifro con otros que quieren catch (...) {} para no hacer nada e incluso quieren que lo haga si hay una infracción de acceso, lo cual me parece una muy mala idea. Si hay un error debido a una mala codificación, no se debe meter los dedos en los oídos y decir en voz alta "¡La la la la la!" para que no tengas que bloquear el programa? De hecho, si el código ahora está en mal estado debido a un error de codificación, ¿realmente desea que el código continúe?

Así que mi opinión general es que/EHa crea un código más grande/más lento y permite a los programadores salirse con la suya escribiendo código que si hay un error fatal presente, continuará ejecutándose en un estado indefinido.

BTW, estoy hablando de aplicaciones y código de servicio que es lo que estamos escribiendo en su mayor parte. No controladores de dispositivos de bajo nivel ni nada de eso.

Por favor, comparta sus ideas.

Respuesta

16

/EHa hace dos cosas. En primer lugar, suprime una optimización que omite los filtros de excepción que llaman automáticamente a los destructores de las variables de clase locales si el analizador de código no puede ver ningún código que pueda arrojar una excepción de C++. Esto hace que el desenrollado de la pila sea seguro para cualquier tipo de excepción, no solo una excepción de C++. La sobrecarga para estos filtros de excepción es el tiempo en x86 y el espacio en x86 y x64.

Y sí, altera el comportamiento de catch (...), ahora también filtra cualquier excepción SEH, no solo C++. Esto es de hecho una apuesta porque atrapas todas las cosas realmente desagradables, las excepciones de hardware asíncronas. Aunque personalmente no creo que atrapar todas las excepciones de C++ sea muy defendible tampoco, todavía tiene una vaga idea de en qué medida el estado del programa se mutó y por qué falló.

Realísticamente, deberá pasar al uso de __try/__except para poder escribir su propio filtro de excepciones y evitar detectar las malas. El código de excepción para las excepciones de C++ es 0xe04d5343 ("MSC"). Usar _set_se_translator() sería otro enfoque.

4

Uso/EHa porque es seguro con .NET interoperabilidad, mientras que/EHsc puede no serlo; ver Destructors not called when native (C++) exception propagates to CLR component por ejemplo.

Sin embargo, si se trata de un código específico, el rendimiento adicional realmente importa y no necesita compatibilidad con .NET (o lo que sea), entonces seguro,/EHsc suena bien.

Ni/EHsc ni/EHa atrapan la mayoría de los errores de memoria, por lo que utilizarlos para detectar violaciones de acceso es un caso sin esperanza.

+2

En ningún caso debe tratar de detectar violaciones de acceso. –

+1

Eso es lo que entiendo ... pero tengo personas que escriben catch (...) {} y si/EHa es seleccionado, eso enterraría la violación de acceso que creo. Una cosa es atrapar (...) {cleanup_stuff; lanzar; } pero incluso en ese caso, si se trata de una violación de acceso, ¿está seguro de que cleanup_stuff hará su trabajo? Estás en un mal estado, por lo que probablemente creo que el programa es mejor simplemente estrellarse allí. – MarkS

+3

Estoy trabajando en un sistema cliente/servidor donde si el servidor tiene una excepción (idealmente, cualquier excepción, incluida la infracción de acceso), me gustaría enviar el mensaje de excepción al cliente antes de permitir que se cuelgue el hilo del servidor. De lo contrario, el servidor simplemente deja de responder. –

Cuestiones relacionadas