2011-02-08 11 views
7

È giusto chiamare il numero throw; dal costruttore se qualcosa va storto e non hai idea di come recuperare?lancio senza argomenti per segnalazione di guasto

L'idea è di far crashare l'applicazione con un dump, poiché lo stato è sconosciuto. O dovresti sempre specificare un argomento?

Da MSDN ho trovato solo che retrocede se non ci sono argomenti, ma non ha idea di cosa succederebbe se non ci fosse un'eccezione iniziale a rethrow.

+0

Se si vuole ottenere un crash, basta 'abort()' o 'assert (false)'. Ciò fornirà un dump (a seconda della configurazione del sistema) ed è meno confuso di un messaggio di errore che dice che il programma è stato interrotto a causa di un 'lancio;' senza alcuna eccezione precedente. –

risposta

11

Se non ci sono eccezioni attualmente in fase di elaborazione, throw; porteranno a terminate() being called immediately e questo interromperà il programma in modo anomalo. Non è molto conveniente - avrai meno informazioni su ciò che è successo rispetto a un'eccezione significativa. Potresti aver generato un'eccezione significativa, rilevarlo al livello più alto (come main()), scrivere alcuni dati diagnostici e quindi terminare il programma.

+1

C'è un piccolo vantaggio in un dump del programma: puoi controllare quale sia lo stato dell'intero programma e provare ad analizzare come il sistema è arrivato. Tendo a generare un'eccezione quando riesci a recuperare e muoio quando non puoi, in modo che la maggior parte dello stato possa essere elaborata. –

+0

Hmm, sì, lo srotolamento dello stack è indesiderato in questo caso. Ma Terminate non salva le informazioni sullo stack, vero? – Coder

1

Tecnicamente, è possibile farlo perché senza argomenti e senza un'eccezione attiva chiama solo terminate() che per impostazione predefinita chiama abort(). Preferisco chiamare direttamente lo abort(), richiede meno sforzi cognitivi per riconoscere cosa sta succedendo.

2

un'asserzione potrebbe rendere la vita più facile a dignose cosa sta andando male

+0

Non funziona nelle versioni di rilascio. –

+0

@Maxim: se la suite di test è completa, non è necessario il test in build di rilascio (di solito mantengo il test ma lancio invece ...) –

+1

Alcuni errori possono rivelarsi solo nelle versioni di rilascio. –

9

No. throw; è una sintassi speciale che ri-getta eccezione corrente. Ha senso solo all'interno dei blocchi catch (o del codice chiamato da uno) per continuare a propagare l'eccezione.

Basta usare:

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

o anche solo

throw "some description"; 

ma il secondo è più brutto per gestire e in generale visto di buon occhio.

+0

Tecnicamente puoi usare 'throw;' ovunque. – sharptooth

+0

non usare 'buttare" qualche descrizione ";', quello che passi dovrebbe derivare da 'std :: exception', altrimenti l'uomo nero verrà a prenderti. –

+0

@sharptooth: Modificato "può essere utilizzato solo" -> "ha senso" essere formalmente corretto. –

2

Mentre tecnicamente puoi chiamarlo, non farà quello che desideri.

La soluzione più semplice è chiamare throw std::runtime_exception("thrown from Foo");, che allo stesso tempo fornisce un feedback su ciò che stava accadendo.

+0

Basta fare in modo che la classe di eccezione fatale catturi la traccia dello stack. –

+0

@Maxim: anche molto utile, infatti tutte le eccezioni lo fanno, è molto più facile risalire in questo modo. –

2

Quando dici "non hai idea di come recuperare" cosa intendi presumo è che a questo punto non sai come gestire l'errore?

Forse non si ottiene il punto di eccezioni. Tu lanci informazioni: che l'eccezione si è verificata e perché. Lo stack di chiamate viene quindi svolto al punto in cui può essere gestito. A quel punto del codice sappiamo come, se possibile, recuperare.

+0

Sì, si è verificata una condizione impossibile, inattesa, come errore non documentato nella libreria di terze parti, errore di memoria insufficiente, bit flip o qualcosa di simile. – Coder