Reading The C++ Programming Language (4th edition), in the Exception Handling chapter, there's an example helper for ad hoc cleanup code:
template<typename F>
struct Final_action {
Final_action(F f): clean{f} {}
~Final_action() { clean(); }
F clean;
};
template<class F>
Final_action<F> finally(F f)
{
return Final_action<F>(f);
}
It's used like
auto act1 = finally([&]{ delete p; });
to run the lambda code at the end of the block in which act1 is declared.
I suppose this worked for Stroustrup when he tested it, due to Return Value Optimization limiting Final_action<>
to a single instance - but isn't RVO just an optional optimization? If the instance is copied on return from finally, obviously ~Final_action()
runs for both copies. In other words, p
is deleted twice.
Is such behavior prevented by something in the standard, or is the code just simple enough for most compilers to optimize it?