Opinions please?
-----Original Message----- From: Peter Dimov Sent: Tuesday, 1 February 2022 06:48 To: 'boost'
Subject: boost::throw_exception potential changes 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?