Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2022-02-01 04:48:09


Currently, `boost::throw_exception(x)` automatically throws
an exception derived from `x` that (1) injects a boost::exception
base class if there's none, and (2) injects a base class that enables
boost::exception_ptr support (boost::current_exception and
boost::rethrow_exception.)

This is convenient, but the downside is the amount of generated
code, e.g. https://godbolt.org/z/5T8T8GEqP (422 lines) compared
to https://godbolt.org/z/1zr1odf7n (36 lines.)

This is not the end of the world as this code is only generated once
per exception type, not on every call to throw_exception, but it's
still unpleasant to see.

It so happens that boost::exception_ptr has recently acquired the
ability to work under C++11 without the need for the supporting
base class, by using the standard std::exception_ptr infrastructure.
So if we also remove the automatic injection of boost::exception
as a base class, and ask users to derive their exceptions from it if
they desire having it as a base, it's possible to simplify
boost::throw_exception considerably.

The normal call now can be almost the same as the naked throw,
https://godbolt.org/z/WssWzfrfW (47 lines.)

And if BOOST_THROW_EXCEPTION is used, which still adds the
source location (file/line/function) to the exception, the result is
97 lines. (https://godbolt.org/z/nETnqrsx8)

However, there is a downside. Due to the way std::exception_ptr
works under GCC/Clang (and all compilers using the same ABI),
the exception is never copied, not when it's captured with
std::current_exception (and consequently boost::current_exception),
nor when it's rethrown with boost/std::rethrow_exception.

This causes problems if an exception is captured, rethrown,
caught and modified, then rethrown again using the same
exception_ptr. The second rethrow throws the modified
exception.

This problem can be seen in https://godbolt.org/z/K9eh71ovP.

So... what do we do? Should I go ahead with these changes to
throw_exception (having a macro to revert to the old behavior,
of course)? Or is that too much of a break?

We can of course offer the same functionality as part of
Boost.Exception, like boost::exception::raise, or similar, but
would that be enough to offset the inconvenience?


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