Boost logo

Boost :

From: Emil Dotchevski (emil_at_[hidden])
Date: 2007-09-30 16:58:56


> I'm not keen on the use of operator<< to add the data to the exceptions.

I do share your concern, but consider that whatever we use for boost
exception should support easy composition, because it needs to work
when used in a throw expression directly:

throw my_error() <<
    error_info<tag_errno>(errno) <<
    error_info<tag_name>(name);

Instead of << we could use .add:

throw my_error().
    add(error_info<tag_errno>(errno)).
    add(error_info<tag_name>(name));

This isn't bad, but in my opinion the << syntax is better despite my
strong dislike for operator overloading.

> <snip>
> catch (some_exception& E) {
> E << " while frobinacting at warp level " << warp_level;
> throw;
> }
>
> Of course this isn't going to work.

Right, it's not going to compile.

> Is "exception" the best choice of name for this library? The name
> boost::exception might give the impression that it's the base class for
> all Boost exceptions, which is not the case;

In my ideal world, the functionality of boost::exception would be
implemented directly by std::exception ;)

That said, there is an easy way to make boost::exception the base of
all exception emitted by boost:

#ifdef BOOST_NO_EXCEPTIONS
namespace boost
{
    void throw_exception(std::exception const & e); // user defined
}
#else
#include <boost/exception.hpp>

namespace boost
{
    template<class E> void throw_exception(E const & e)
    {
        throw enable_error_info(e); //see documentation
    }
}
#endif

(I'm now thinking we need to add some trickery to enable_error_info,
so it does not inject boost::exception as a base if it is a base
already.)

This adds very little overhead to all exceptions: an empty shared_ptr,
which does not allocate any memory. The benefit is that now user code
can catch any boost exception as a boost::exception, and add
application-specific error information to exceptions coming from boost
libraries:

try
{
    ---use boost---
}
catch( boost::exception & x )
{
    x << error_info<my_info>(.....);
    throw;
}

> Also, there's the possibility that someone might propose some other
> exception-related library, orthogonal to this one, in the future. How
> about "tagged_exception"?

I think there is a lot of value to enabling all exceptions to carry
arbitrary failure-related information. The main motivation for Boost
Exception is that a library that throws an exception can not possibly
anticipate everything that is relevant to that type of failure in a
particular client application.

I think that even if a particular library has no info to add to an
exception, it should throw exceptions that derive from Boost
Exception, even if it's just to enable information to be added later
on.

If you agree with the above, I think you'd agree that boost::exception
is the appropriate name to use.

That said, I am very much interested all negative feedback. Do you see
any reasons why you wouldn't want to use Boost Exception as a base for
all of your exceptions? Do you think the current design of Boost
Exception can be improved so it better serves its intended design goal
as universal base class that can transport arbitrary failure-related
data to the catch site?

> You might like to say something about the overhead that is added, i.e.
> that there is a std::list<something> in each exception (or whatever).
> (Remember that there are still plenty of people who dislike exceptions
> because of the perceived overhead that they involve.)

In this particular library we shouldn't be concerned with people who
don't like exceptions because of the exception handling overhead
itself.

As for the additional overhead of Boost Exception, the price you pay
if you don't add any info to it is an empty shared_ptr. If you do add
info, then more memory is allocated -- however notice that all of that
memory is allocated only when throwing exception, and that it is freed
when the exception is handled. I can't imagine a use case when that
would cause any issues.

> I think you do say something about the exception guarantee, but it
> might be useful to add a more explicit section near the start
> describing the exception guarantee and also whether any dynamic memory
> allocation is involved; what happens if the exception that was thrown
> was "out of memory"?

That's in the FAQ already. :)

Emil Dotchevski


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