Boost logo

Boost :

Subject: Re: [boost] [scope_exit] D-style scope(failure) and scope(success) in C++
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2013-09-29 18:55:01


On Sun, Sep 29, 2013 at 2:23 PM, Evgeny Panasyuk
<evgeny.panasyuk_at_[hidden]> wrote:
> 27.09.2013 3:24, Emil Dotchevski:
>
>> Is there a use case for uncaught_exception_count other than to
>> implement D-style scope-exit/-failure?
>
>
> scope(failure)/scope(success) would be main use case, however - there are
> several others:
>
> 1. scope(failure/success) runs specified code block. Sometimes such code
> block can be reused - in that case custom guard object is preferred over
> copy-pasting code.

That is still the scope failure use case, which presumably has to deal
with exceptions in the failure branch. I don't object to scope
exit/failure dealing with exceptions any way its designers think it
should.

> 2. Temporary objects:
> log() << may_throw() << endl;
> log() returns some temporary object which does some finalizing work in
> destructor. If that destructor is called due to stack unwinding - then
> finalizing part will be different.

Here, if may_throw() throws, ~log() must not throw. Therefore it is
possible for the user to not be notified about a logging failure. If
it is critical for the user to be notified about all logging failures,
then then ~log() must not do any logging. How critical this
notification is doesn't depend on whether or not may_throw() emits an
exception.

> 3. Stack objects which do work in destructor that may fail.
> Traditional example is File object which requires flush(may fail) and
> release handle at the end of lifetime.
> Typical solution is to place .flush() manually and release handle in
> destructor:
> {
> File a,b;
> // ...
> b.flush(); // may throw
> a.flush(); // may throw
> }

The motivation here is to support throwing destructors. This becomes a
self-fulfilling prophecy: you write destructors that may throw, which
forces everyone else to deal with that. It is incorrect for objects
that are no longer needed to be able to fail to go away, therefore
destructors must not throw. So, I'd consider flush()ing elsewhere.

-- 
Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

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