Boost logo

Boost :

From: me22 (me22.ca_at_[hidden])
Date: 2005-11-10 10:32:35


On 10/11/05, Alexander Nasonov <alnsn-boost_at_[hidden]> wrote:
> Is there an interest to write something like this
>
> int i = 2, j = 1;
>
> BOOST_FINALLY_BEGIN( (i)(j) )
> {
> std::cerr << i + j << '\n';
> } BOOST_FINALLY_END
>
> in a code to make sure that a code inside finally block
> is always executed when leaving a scope?
>

Personally, I prefer the ScopeGuard-styled version. I have code that
makes the following type of code work, if there's interest:
int i = 2, j = 1;
BOOST_FINALLY( std::cerr << ( boost::lambda::var(i) +
boost::lambda::var(j) ) << '\n' );

The idea being that the macro simply expands to a
line-number-dependant identifier of a ScopeGuard-style type (
http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm )
which, since it can never be dismissed, always calls the functor. The
code itself is quite short, since it assumes that bind, lambda, or
similar would be used to create the functor. With
function<void(void)> it would be incredibly trivial, but, as described
in the above article, the trick used avoids some otherwise-necessary
virtual function calls.

Also, I think it would be best if your code wrapped the code in the
destructor in a try block to eat all exceptions thrown. ( Although
your version does allow the user to write his own try block around the
code directly, so it's not totally necessary. Of course, this could be
done in the ScopeGuard-style version as well by providing a functor
adaptor that eats exceptions, were it decided that always having the
try block is unacceptable. ) Personally, I think that the
exception-eating version should be default, in the interest of safety.
 Good compilers ought to remove them when they're obviously
unnessesary anyways. Of course, the finally block is only really
useful if the operation is nofail, but...

- Scott McMurray


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk