2015-01-02 15 views
9

Ho appena notato sopra suPerché std :: uncaught_exception cambia in std :: uncaught_exceptions?

http://en.cppreference.com/w/cpp/error/uncaught_exception

che C++ 17 sostituirà std::uncaught_exception(), che restituisce un bool, con std::uncaught_exceptions(), che restituisce un int.

L'aggiunta allo standard che descrive questo è qui:

http://isocpp.org/files/papers/n4259.pdf

Non fornisce il razionale ma dice

[Nota: Quando uncaught_exceptions()> 0, il lancio di un'eccezione può dare in una chiamata di std :: terminate() (15.5.1). - end note]

che è stranamente vago.

Qual è la ragione di questo cambiamento? Sono possibili più eccezioni attive in C++ 17 o in una versione futura dello standard?

+1

È possibile che esistano più eccezioni attive in tutte le versioni di C++. 'struct foo {~ foo() {try {throw new int; } catturare (...) {} } }; int main() {{foo f; lanciare un nuovo doppio; } catch (...) {}} 'ha due eccezioni attive mentre distruggiamo' f'. – Yakk

+1

Vedere anche [questo CppCon 2015 talk] (https://github.com/CppCon/CppCon2015/blob/master/Presentations/Declarative%20Control%20Flow/Declarative%20Control%20Flow%20-%20Andrei%20Alexandrescu%20-% 20CppCon% 202015.pdf) di Andrei Alexandrescu per informazioni su 'ScopeGuard' e N4259. – Adversus

risposta

18

La carta che ha introdotto questo era n4152, che ha la logica (che bolle in genere fino a "rendere il lavoro ScopeGuard")

citare,

come documentato almeno dal 1998 in Guru di the Week # 47, significa codice che viene chiamato in modo transitorio da un distruttore che potrebbe essere invocato durante lo srotolamento dello stack e non può rilevare correttamente se esso stesso viene effettivamente chiamato come parte dello svolgimento. Una volta che ti stai liberando da qualsiasi eccezione, a uncaught_exception tutto sembra essere srotolato, anche se c'è più di un'eccezione attiva.

E

questo utilizza le informazioni già presenti nelle principali implementazioni, dove le attuali implementazioni di ScopeGuard ricorso al codice portabile che si basa sulle caratteristiche del compilatore non documentate per rendere ScopeGuard “portatile in pratica” di oggi. Questa opzione propone di aggiungere una sola nuova funzione per esporre le informazioni che già presenti in compilatori, in modo che questi usi possono essere veramente portatile

PS: Ecco un esempio di come questa funzione può essere implementata utilizzando le informazioni del compilatore-speicific: https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp

e per un semplice esempio in cui viene utilizzato, non guardare oltre "pompa di record" di boost.log (vedi boost/log/detail/format.hpp e boost/log/sources/record_ostream.hpp): essa rende possibile per BOOST_LOG(lg) << foo(); per accedere al distruttore dell'oggetto guardia crea se foo non lancia, cioè se il numero di eccezioni in volo quando viene chiamato il distruttore non è maggiore t han quando è stato chiamato il costruttore.

+8

Un esempio che mostra come possono esistere più eccezioni attive potrebbe essere illuminante. – Yakk

-1

std :: uncaught_exception() rileva solo se lo stack si srotola. In un lavoro di Herb Sutter, sottolinea che ciò non indica in modo affidabile che esiste un'eccezione attiva. Herb afferma che questo è "quasi" utile.Ho incontrato una situazione in cui questo è davvero ambiguo, che è quello che mi ha portato a questo post.

std :: uncaught_exceptions() viene specificato come restituire il numero di eccezioni attive, che è effettivamente utile.

-1

nota che std :: uncaught_exception() può essere ancora utile per debug/loginfo. Può aiutare a determinare la provenienza dell'eccezione. Tuttavia sono d'accordo sul fatto che sia abbastanza inutile.

Problemi correlati