Estoy leyendo sobre el manejo de excepciones. Obtuve información sobre qué es el manejo de excepciones, pero tengo algunas preguntas:
- ¿Cuándo lanzar una excepción?
- En lugar de lanzar una excepción, ¿podemos usar un valor de retorno para indicar el error?
- Si protejo todas mis funciones mediante bloques try-catch, ¿no reducirá el rendimiento?
- ¿Cuándo usar el manejo de excepciones?
- Vi un proyecto donde todas y cada una de las funciones de ese proyecto contenían un bloque try-catch (es decir, el código dentro de toda la función está rodeado por un bloque try-catch). ¿Es esta una buena practica?
- ¿Cuál es la diferencia entre try-catch y __try __except?
c++
windows
exception
exception-handling
Umesha MS
fuente
fuente
Respuestas:
Aquí hay una guía bastante completa sobre excepciones que creo que es una lectura obligada:
Excepciones y manejo de errores - Preguntas frecuentes de C ++ o Preguntas frecuentes de C ++ lite
Como regla general, una excepción cuando el programa puede identificar una externaproblema que impide la ejecución. Si recibe datos del servidor y esos datos no son válidos, inicie una excepción. ¿Sin espacio en disco? Lanza una excepción. ¿Los rayos cósmicos le impiden consultar la base de datos? Lanza una excepción. Pero si obtiene algunos datos no válidos desde el interior de su propio programa, no lance una excepción. Si su problema proviene de su propio código incorrecto, es mejor usar ASSERT para protegerse contra él. El manejo de excepciones es necesario para identificar problemas que el programa no puede manejar e informarles sobre el usuario, porque el usuario puede manejarlos. Pero los errores en su programa no son algo que el usuario pueda manejar, por lo que el bloqueo del programa indicará no mucho menos que "¡El valor de answer_to_life_and_universe_and_everything no es 42!
Detecte una excepción en la que pueda hacer algo útil con ella, como mostrar un cuadro de mensaje. Prefiero detectar una excepción una vez dentro de una función que de alguna manera maneja la entrada del usuario. Por ejemplo, el usuario presiona el botón "Annihilate all hunams", y dentro de la función annihilateAllHunamsClicked () hay un bloque try ... catch para decir "No puedo". Aunque la aniquilación de hunamkind es una operación compleja que requiere llamar a docenas y docenas de funciones, solo hay un intento ... atrapar, porque para un usuario es una operación atómica: hacer clic en un botón. Los controles de excepción en todas las funciones son redundantes y desagradables.
Además, no puedo recomendar lo suficiente que se familiarice con RAII, es decir, para asegurarse de que todos los datos que se inicializan se destruyen automáticamente. Y eso se puede lograr inicializando tanto como sea posible en la pila, y cuando necesite inicializar algo en el montón, use algún tipo de puntero inteligente. Todo lo que se inicialice en la pila se destruirá automáticamente cuando se produzca una excepción. Si usa punteros tontos de estilo C, corre el riesgo de pérdida de memoria cuando se lanza una excepción, porque no hay nadie que los limpie en caso de excepción (claro, puede usar punteros de estilo C como miembros de su clase, pero asegúrese de que sean cuidado en destructor).
fuente
fclose
entonces!). No le dará un seguimiento de pila completo.Las excepciones son útiles en una variedad de circunstancias.
Primero, hay algunas funciones en las que el costo de calcular la condición previa es tan alto que es mejor simplemente hacer el cálculo y abortar con una excepción si se encuentra que la condición previa no se cumple. Por ejemplo, no puede invertir una matriz singular, sin embargo, para calcular si es singular, calcula el determinante que es muy costoso: puede que tenga que hacerse dentro de la función de todos modos, así que "intente" invertir la matriz e informe un error si no puede lanzar una excepción. Esta es básicamente una excepción como uso de condiciones previas negativas .
Luego, hay otros casos en los que su código ya es complejo y es difícil pasar información de error por la cadena de llamadas. Esto se debe en parte a que C y C ++ tienen modelos de estructura de datos defectuosos: hay otras formas mejores, pero C ++ no las admite (como el uso de mónadas en Haskell). Este uso es básicamente que no me molestaría en hacerlo bien, así que lanzaré una excepción : no es la forma correcta, pero es práctica.
Luego está el uso principal de las excepciones: informar cuando las condiciones previas externas o invariantes, como recursos suficientes como memoria o espacio en disco, no están disponibles. En este caso, normalmente terminará el programa, o una subsección importante del mismo, y la excepción es una buena forma de transmitir información sobre el problema. Las Excepciones de C ++ fueron diseñadas para informar errores que impiden que el programa continúe .
Se sabe que el modelo de manejo de excepciones utilizado en la mayoría de los lenguajes modernos, incluido C ++, no funciona. Es demasiado poderoso. Los teóricos ahora han desarrollado mejores modelos que el modelo completamente abierto de "arrojar cualquier cosa" y "tal vez y tal vez no atraparlo". Además, el uso de información de tipo para clasificar excepciones no fue una muy buena idea.
Entonces, lo mejor que puede hacer es lanzar excepciones con moderación, cuando hay un error real y cuando no hay otra forma de lidiar con él y detectar excepciones lo más cerca posible del punto de lanzamiento .
fuente
No estoy de acuerdo con este aspecto de la respuesta aceptada . Una afirmación no es mejor que lanzar una excepción. Si las excepciones fueran adecuadas solo para errores en tiempo de ejecución (o "problemas externos"), ¿
std::logic_error
para qué sirve ?Un error lógico es casi por definición el tipo de condición que impide que un programa continúe. Si el programa es una construcción lógica y ocurre una condición fuera del dominio de esa lógica, ¿cómo puede continuar? ¡Reúna las entradas mientras pueda y haga una excepción!
No es que no haya arte previo.
std::vector
, por nombrar solo uno, arroja una excepción de error lógico, a saberstd::out_of_range
. Si usa la biblioteca estándar y no tiene un controlador de nivel superior para detectar excepciones estándar, aunque solo sea para llamar a qué () y salir (3), entonces sus programas están sujetos a una terminación repentina y silenciosa.Una macro de aserción es una guardia mucho más débil. No hay recuperación. A menos que, es decir, no esté ejecutando una compilación de depuración, en cuyo caso no hay ejecución . La macro de aserción pertenece a una era en la que el cálculo era 6 órdenes de magnitud más lento que en la actualidad. Si se toma la molestia de probar errores lógicos, pero no usar esa prueba cuando sea necesario, en producción, ¡será mejor que tenga mucha confianza en su código!
La biblioteca estándar proporciona excepciones de errores lógicos y las emplea. Están ahí por una razón: porque ocurren errores lógicos y son excepcionales. El hecho de que C presente aserciones no es motivo para confiar en un mecanismo tan primitivo (y posiblemente inútil), cuando una excepción maneja el trabajo mucho mejor.
fuente
Mejor lectura para esto
Se ha hablado mucho sobre el manejo de excepciones durante la última década y media. Sin embargo, a pesar de un consenso general sobre cómo manejar adecuadamente las excepciones, sigue existiendo una división en el uso. El manejo inadecuado de excepciones es fácil de detectar, fácil de evitar y es una métrica de calidad de código (y desarrollador) simple. Sé que las reglas absolutas parecen cerradas o exageradas, pero como regla general, no deberías usar try / catch
http://codebetter.com/karlseguin/2010/01/25/don-t-use-try-catch/
fuente
try
/catch {}
?Se incluye una verificación de excepción en el código cuando existe la posibilidad de obtener una excepción como resultado o en algún punto intermedio entre el problema.
2.Use el bloque try-catch solo con aquellos casos en los que sea necesario. El uso de cada bloque try-catch se suma a una verificación de condición adicional que ciertamente reduce la optimización del código.
3.Creo que _try_except es un nombre de variable válido ...
fuente
La diferencia básica es:
uno es tu propio.
Por ejemplo, tiene una expresión que podría hacer
0 divide error
. Usar try catch1.
le ayudará cuando ocurra un error. O si necesita unaif a==0 then..
en2.
Si no intenta capturar la excepción, no creo que sea más rápido, simplemente se omite, si
error
ocurre, seráthrew
para un controlador externo.Entregarte a ti mismo significa que el problema no irá más lejos pues tienes ventaja en velocidad en muchos casos, pero no siempre.
Sugerir: manejarse usted mismo cuando sea simple y lógico.
fuente
Muchos puristas de C / C ++ desalientan las excepciones por completo. Las principales críticas son:
En su lugar, verifique el valor de retorno / código de error cada vez que llame a una función.
fuente