2009-06-04 25 views
15

En general, tiendo a utilizar try/catch para código que tiene múltiples puntos de falla para los cuales los fallos tienen un controlador común.Uso de bloques try/catch en C++

En mi experiencia, este suele ser un código que califica la entrada o el contexto antes de realizar alguna acción o salida después de realizar alguna acción.

He recibido asesoramiento de la literatura y colegas para minimizar el código en dichos bloques y acepto que, en general, es un buen consejo.

Me gustaría entender un poco más sobre la base de los consejos anteriores:

  • ¿Cuál es la naturaleza de los gastos generales?
  • ¿Existen directrices de desarrollo recientes que aborden el uso recomendado (o evitación) de los bloques try/catch?
  • ¿Cuánto cuestan los procesadores más rápidos y los compiladores más modernos mitigar los problemas con try/catch?

Gracias de antemano por la ayuda,

AJ

+0

No estoy seguro de entender la pregunta. ¿Te preocupa el rendimiento de los bloques try/catch? ¿O preguntar sobre el uso de try/catch para manejar la validación de entrada o qué? – jalf

+0

Dupe de http://stackoverflow.com/questions/43253/measuring-exception-handling-overhead-in-c entre muchos otros –

Respuesta

0

En mi experiencia, el mayor problema con bloques try/catch son a menudo tratamos de capturar las excepciones demasiado genérica. Por ejemplo, si envuelvo mi función principal con un bloque try/catch que atrapa (...) Básicamente, estoy tratando de no permitir que mi programa falle b/c de una excepción lanzada.

El problema con este enfoque como lo veo es doble. 1) Mientras estoy probando y depurando, no veo ningún error y no tengo la oportunidad de solucionarlo. 2) Es realmente una especie de tomar la salida perezosa. En lugar de pensar a través de los problemas que pueden surgir y descubrir cuáles son los casos extremos, estoy tratando de no fallar. Tratar de no fallar es muy diferente a tratar de tener éxito.

+1

Siempre puede atrapar y volver a lanzar. Nota: Si una excepción escapa de main(), se implementa definida si la pila se desenrolla (por lo que no se pueden invocar destructores). Por lo tanto, siempre capturo (...) e inicio de sesión principal y vuelvo a lanzar para que aparezca el mensaje de error de Windows. –

5

Para su segunda pregunta: las pautas generales son here, Herb Sutter también da muy buenos consejos here.

6

Encontré a technical report on C++ performance (advertencia en pdf) que incluye una sección sobre excepciones. Puede que le resulte interesante. He tenido compañeros de trabajo que creían que había sobrecarga en cada instrucción dentro de un bloque try/catch, pero este informe técnico no parece apoyar esa idea.

+0

Ese enlace ahora redirige a http://www.stroustrup.com/ :( –

+0

@ShawnChin: Así fue. He encontrado un nuevo enlace, y también me di cuenta de que atribuí mal el artículo. He corregido la publicación. –

+0

Una versión más reciente de ese informe está disponible aquí: http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf –

0

En la mayoría de los lenguajes que entran y salen de un bloque try/catch a través de los métodos normales es gratuito, solo cuando se lanza una excepción el manejador de excepciones busca dónde manejar la excepción.

2

Depende de un compilador. ¿Por qué no escribe una función simple con un bloque try-catch y uno similar sin él y compara el código máquina generado?

17

en C++, el costo depende de la aplicación. En general, hay dos formas de implementar excepciones:

El primero es el enfoque de "tabla". El compilador crea un conjunto de tablas para buscar, en el punto donde se lanza la excepción, dónde ir.Cuando se lanza la excepción, tiene que buscar en cada tabla la pila de llamadas hasta que encuentre algo que capte esta excepción. Como todo esto se basa en el tiempo de ejecución, entrar o salir de una captura de prueba no produce penalización (bien), pero lanzar una excepción implica potencialmente muchas búsquedas, produciendo un lanzamiento mucho más lento. Yo personalmente prefiero los bloques de captura de prueba que no tienen que pagar, porque las excepciones deberían ser una circunstancia muy rara. Esto también haría los ejecutables más grandes, si tienen que almacenar las tablas.

Los segundos son el enfoque del "código". Cada vez que el código ingresa en un bloque try catch, conceptualmente, la ubicación del bloque se coloca en una pila. Esto produce un costo durante la entrada y la salida de un bloque try-catch; sin embargo, cuando se lanza una excepción, el mecanismo de tiempo de ejecución puede saltar rápidamente de la pila para encontrar dónde ir. Entonces, lanzar excepciones es (¿mucho?) Más rápido, pero ahora ingresar a un bloque tiene un costo. Poner un bloque de captura de prueba en un circuito estrecho de bajo nivel podría producir una sobrecarga significativa.

Debería comprobar su compilador específico para ver cuál utiliza.

0

En C++ no debe usar los bloques try/catch para realizar la limpieza. En su lugar, es posible que desee utilizar plantillas para realizar adquisiciones de recursos.

auto_ptr de son una [mala] ejemplo

cerraduras de sincronización, en donde almacena un mutex como una variable de estado, y utiliza variables locales (plantillas o clases regulares) para realizar la .acquire() /. Release() métodos.

Cuantos más cosas haga, menos tendrá que preocuparse por la liberación manual de objetos en condiciones excepcionales. El compilador de C++ lo hará por usted.