Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-02-12 10:38:16


Brock Peabody wrote:
>> -----Original Message-----
>> From: boost-bounces_at_[hidden]
>> [mailto:boost-bounces_at_[hidden]] On Behalf Of David Abrahams
>
>>> I'd rather be able to put them all in a list than to have to
>>> manually register each one.
>>
>> ?? it seems equivalent to me.
>
> Maybe I'm too lazy, but
>
> <exception1, exception2, ... >
>
> is a little more compact than
>
> register_<exception1>();
> register_<exception2>();
> ...

Well,

    register_<exception1, exception2, ...>();

isn't that hard to implement. But that's not really the point. The point is
that you can place the register_ calls in multiple translation units, and
you can register_ your library's exceptions even if you don't create any
threads, and you don't expose their actual types to the world.

>> Yup. More importantly, it works even if different libraries register
>> separate translators for exceptions in the same class hierarchy,
>> without regard to registration order.
>
> That's one thing I guess I'm missing - where would the runtime register
> live? In Daniel Wallin's implementation it the register was a singleton,
> but wouldn't you want a separate register for each thread/thread_group?

No, not really. There are two related, but distinct, notions that are being
mixed up, "how" to transport exception X, and "whether" to transport
exception X from the thread procedure to the join point.

The ability to transport an exception is not coupled to any thread, or to a
particular thread library, for that matter. You need to be able to copy the
exception and to throw it at run time without having access to its type.
When we discussed the issue I proposed that exceptions derived from:

struct transportable_exception
{
    virtual auto_ptr<transportable_exception> clone() const = 0;
    virtual void rethrow() const = 0;
};

be automatically transportable without any registration; a helper

template<class E> void throw_transportable_exception(E const & e);

can take care of injecting the base class automatically.

This can, of course, be combined with an explicit register_<>, and all
standard library exceptions need also be transportable by default, without
registration. A generic unregistered std::exception should, as you pointed
out, be converted to unknown_exception with the what() string preserved.

That's the "how" part.

The "whether" part is that we (arguably) need the ability to specify a list
of "expected" exception base classes at thread creation time. I'm still not
sure about that, since this is for all intents and purposes an exception
specification. Much the same effect can be achieved by just decorating the
thread function with one.


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