Mi sono imbattuto in uno scenario interessante con il controllo del flusso mentre lavoravo sulla mia lingua. Cosa succede se viene generata un'eccezione durante l'elaborazione di un'istruzione break
. GCC sembra credere che il flusso di rottura è perso, ma lo standard sembra un po 'in silenzio su ciò che dovrebbe accadere.L'interruzione/proseguimento/ritorno dovrebbe essere interrotta da un'eccezione?
Ad esempio, cosa dovrebbe fare effettivamente il seguente programma?
#include <iostream>
using namespace std;
struct maybe_fail {
bool fail;
~maybe_fail() {
if(fail)
throw 1;
}
};
int main() {
for(int i=0; i < 6; ++i) {
cout << "Loop: " << i << endl;
try {
maybe_fail mf;
mf.fail = i % 2;
if(i == 3)
break;
} catch(int) {
cout << "Caught" << endl;
}
}
return 0;
}
noti che un return
verrà bloccata anche, così come un continue
(aggiungere uscita dopo la cattura di vedere che). Tentativo di goto
anche al di fuori del blocco.
Qual è il flusso corretto? Lo standard non sembra rispondere a questo: la sezione 6.6 sulle dichiarazioni di salto non fa menzione, né la sezione 15 sulla gestione delle eccezioni. Capisco che le eccezioni nei distruttori sono in una forma terribilmente brutta, ma se si utilizza qualcosa come BOOST_SCOPE_EXIT per le dichiarazioni di rinvio, questo comportamento potrebbe diventare piuttosto importante.
Forse di interesse, lo stesso flusso si verifica in Java e Python, quindi almeno sembra esserci una certa coerenza nei linguaggi imperativi.
La tua domanda sembra confermare il consiglio nelle FAQ C++: http://www.parashift.com/c++-faq-lite/dtors-shouldnt-throw.html In pratica, non lanciare eccezioni nei distruttori. Questa domanda nelle FAQ stava dicendo come viene chiamato 'terminate()' se ci si trova in una situazione di "gestione delle eccezioni doppie", ma il tuo esempio sembra continuare il consiglio che è solo brutto farlo. –
@Kevin, assolutamente, quel consiglio si estenderebbe quindi a qualsiasi istruzione "differita" come in qualsiasi lingua (incluso BOOST_SCOPE_EXIT per C++). –
in quale altro modo interpreteresti il comportamento? lanciare l'eccezione nel distruttore e poi cosa? – bdwain