2011-02-08 6 views
7

¿Está bien simplemente llamar al throw; desde el constructor si algo sale mal y no tiene idea de cómo recuperarlo?throw without arguments for failure signaling

La idea es dejar que la aplicación se bloquee con un volcado, ya que el estado es desconocido. ¿O debería siempre especificar un argumento?

De MSDN Solo encontré que vuelve a surgir si no hay ningún argumento, pero no tengo idea de qué sucede si no hay una excepción inicial para volver a lanzar.

+0

Si desea obtener un bloqueo, simplemente 'abort()' o 'assert (false)'. Eso proporcionará un volcado (dependiendo de la configuración de su sistema) y es menos confuso que un mensaje de error que diga que el programa terminó debido a un 'throw;' sin excepción previa. –

Respuesta

11

Si no hay una excepción que actualmente se está procesando throw; llevará a terminate() being called immediately y eso terminará su programa anormalmente. Eso no es muy conveniente: tendrás menos información sobre lo sucedido en comparación con arrojar una excepción significativa. Podría haber lanzado una excepción significativa, atraparla en el nivel superior (como main()), escribir algunos diagnósticos y luego finalizar el programa.

+1

Hay una ligera ventaja en un volcado de programa: puede inspeccionar cuál es el estado de todo el programa e intentar analizar cómo llegó el sistema allí. Tiendo a arrojar una excepción cuando puede recuperarse, y muero cuando no puede, de modo que se puede procesar la mayoría del estado. –

+0

Hmm, sí, el desenrollado de la pila no es deseado en este caso. Pero Terminate tampoco guarda la información de la pila, ¿o sí? – Coder

1

Técnicamente, puede hacerlo porque lanzar sin argumento y sin una excepción activa simplemente llama a terminate() que por defecto llama al abort(). Prefiero llamar directamente al abort(), requiere menos esfuerzo cognitivo para reconocer lo que está sucediendo.

2

una aserción puede hacer su vida más fácil a dignose lo que va mal

+0

No funciona en compilaciones de lanzamiento. –

+0

@Maxim: si el conjunto de pruebas es completo, no necesita la prueba en compilaciones de lanzamiento (generalmente guardo la prueba, pero tiro en su lugar ...) –

+1

Algunos errores solo pueden revelarse en versiones de lanzamiento. –

9

throw; es una sintaxis especial que re-lanza excepción actual. Solo tiene sentido dentro de los bloques catch (o código llamado desde uno) para continuar propagando la excepción.

sólo tiene que utilizar:

#include <stdexcept> 
... 
throw std::runtime_error("some description"); 

o incluso sólo

throw "some description"; 

pero el último es más feo de manejar y generalmente mal visto.

+0

Técnicamente puedes usar 'throw;' en cualquier lugar. – sharptooth

+0

no use 'throw 'alguna descripción"; ', lo que arroje debe derivar de' std :: exception', o de lo contrario el hombre del tesoro vendrá a buscarlo. –

+0

@sharptooth: Editado "solo se puede usar" -> "solo tiene sentido" para ser formalmente correcto. –

2

Aunque técnicamente puede llamarlo, no hará lo que le gustaría.

La solución más simple es llamar al throw std::runtime_exception("thrown from Foo");, que al mismo tiempo da algunos comentarios sobre lo que estaba sucediendo.

+0

Simplemente haga que su clase de excepción fatal capture el seguimiento de la pila. –

+0

@Maxim: sí, muy útil también, de hecho, todas nuestras excepciones lo hacen, es tan fácil rastrearlas de esta manera. –

2

Cuando dices "no tengo idea de cómo recuperarme", ¿a qué te refieres supongo que a esta altura no sabes cómo manejar el error?

Quizás no obtenga el punto de las excepciones. Lanzas información: que ocurrió la excepción y por qué. La pila de llamadas se desenrolla hasta el punto en que se puede manejar. En ese punto del código, sabemos cómo, si es posible, recuperarlo.

+0

Sí, se produjo una situación imposible e inesperada, como un error no documentado en una biblioteca de terceros, un error de memoria, un cambio de bit o algo así. – Coder