|
Boost : |
Subject: Re: [boost] [scope_exit] D-style scope(failure) and scope(success) in C++
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2013-09-29 23:53:05
On Sunday 29 September 2013 15:55:01 Emil Dotchevski wrote:
> On Sun, Sep 29, 2013 at 2:23 PM, Evgeny Panasyuk
>
> <evgeny.panasyuk_at_[hidden]> wrote:
>
> > 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.
In case of Boost.Log, ~log() would actually push the log record to the library
for processing (applying final formatting, writing to files/console, etc.). If
the streaming statement fails with an exception, ~log() must not do anything
and let the exception propagate. OTOH, when the streaming expression completes
normally, the record processing may throw itself, which makes ~log() a
throwing destructor. So you see, no errors are lost, but in some cases work
must be suppressed for correct behavior.
Writing throwing destructors is discouraged, everyone knows that. But
sometimes you just need it because it offers benefits compared to other
approaches. unhandled_exception_count() is crucial to make that possible.
There are restrictions for such classes, e.g. they should not be used as
members of other classes or allocated on heap. But log() above is never
intended to be used that way.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk