2013-07-24 5 views
7

sto leggendo il "C++ Programming Language 4a edizione" libro e hanno una domanda per quanto riguarda un paragrafo sulla gestione delle eccezioni:un'eccezione durante la manipolazione un'eccezione

Ci sono casi in cui la gestione delle eccezioni deve essere abbandonato per meno tecniche di gestione degli errori sottili. I principi guida sono:

  • Non generare un'eccezione durante la gestione di un'eccezione.
  • Non lanciare un'eccezione che non può essere catturata.

Se l'implementazione della gestione delle eccezioni ti cattura, lo termina il programma.

Qualcuno potrebbe darmi un esempio del primo situtation? Solo una cosa del genere mi viene in mente ma è un codice valido secondo g ++:

try 
{ 
    throw 1; 
} 
catch(...) 
{ 
    try 
    { 
     throw 2; 
    } 
    catch(...) 
    { 
     cout << "OK"; 
    } 
} 
+2

Non date per scontato qualcosa è valido e/o fa quello che si pensa solo perché è compilato! 'C++' ha il concetto di [* comportamento indefinito *] (http://blog.regehr.org/archives/213), che si traduce approssimativamente come "se fai qualcosa di non valido, tutte le scommesse sono disattivate". Potrebbe andare in crash, potrebbe funzionare, potrebbe sembrare funzionare ma inviare tutti i numeri di carta di credito ai principi nigeriani. Nota che non sto dicendo che questo caso particolare sia (penso che non sia UB, solo pericolosamente vicino), ma non pensate che "sia compilato, va bene". – BoBTFish

+3

Non posso essere d'accordo con il primo di questi, ma posso essere d'accordo con il secondo. Ci sono * molte * volte che i catch-block possono generare eccezioni, inclusa la stessa eccezione (tramite 'throw;'). – WhozCraig

risposta

12

Questo è un po 'fuorviante; va bene lanciare da un gestore di eccezioni (che è quello che capisco da "mentre gestisco un'eccezione"), a patto che ci sia un altro gestore per catturarlo.

Il problema è se si lancia un'eccezione dal distruttore di un oggetto che viene distrutto durante lo srotolamento dello stack. In tal caso, esistono due eccezioni non gestite e il solito meccanismo di eccezione può gestirne solo uno; quindi la risposta è chiamare terminate.

Esempio:

struct dodgy {~dodgy() {throw "Don't do this!";}}; 

try { 
    dodgy d; 
    throw 1; 
} catch (...) { 
    // Never reached: destroying `d` killed the program. 
} 
+0

+1 per il punto sul comportamento del distruttore in un ambiente multi-lancio. Non spesso considerato, ma spesso un problema. Bella recensione. – WhozCraig

+0

Grazie, ho anche trovato una spiegazione molto più dettagliata nello standard: è 15.5.1/1. – Quentin

+0

Puoi usare 'std :: uncaught_exception' per vedere se lanciare un'eccezione ucciderà il programma. –