Many people are no doubt familiar with Mr. Alexandrescus ScopeGuard template (now part of Loki) and the new version ScopeGuard11 presented here: http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C
with source here: https://gist.github.com/KindDragon/4650442
In his talk at c++ and beyond 2012 he mentioned that he couldn't find a way to correctly detect if scope was being exited because of an exception. Therefore he couldn't implement a SCOPE_FAIL macro which would execute the supplied lambda (usually used for roll back code) if and only if the scope exited because of an exception. This would render the dismiss() member function unneeded and make code more readable.
Since I am by no means as genius or experienced as Mr. Alexandrescu I expect implementing SCOPE_FAIL is not as easy as this:
~ScopeGuard11(){ //destructor
if(std::uncaught_exception()){ //if we are exiting because of an exception
f_(); //execute the functor
}
//otherwise do nothing
}
My question is why not?
With a
ScopeGuard11
class that has your destructor, the memberf_
may be called, even if it is not the current scope (that is supposed to be protected by the guard) that is being exited due to an exception. Use of this guard is unsafe in code that might be used during exception cleanup.Try this example:
You'd want to see one
rollback
when leavingbaz
, but you'll see two - including a spurious one from leavingfoo
.