Boost logo

Boost :

Subject: Re: [boost] Boost and exceptions
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2012-06-23 16:46:24


On 06/23/2012 02:25 PM, Robert Ramey wrote:
> Steven Watanabe wrote:
>>> So - boost::throw_except is changed and.... what? I already included
>>> all the useful information I can add. How can boost::throw_exception
>>> add to this on it's own?
>> It can't. Boost.Exception allows /callers/
>> of your library to add their own information
>> to the exception if they have more context
>> than the Serialization library itself does.
> agreed - but one doesn't need boost.exception to do that.

It isn't strictly necessary, but it makes
things a lot easier.

>> try {
>> throw enable_current_exception(x);
>> } catch(...) {
>> exception_ptr e = current_exception();
>> }
>> // move e to another thread
>> rethrow_exception(e);
> OK - get it - but I don't see that it adds any value compared to
> try {
> throw x;
> }
> catch(...){
> exception_ptr e = std::current_exception();
> std::rethrow_exception(e); // n3242 18.8}
> }

It doesn't. For compilers that support
std::current_exception, boost::enable_current_exception
can be a no-op.

>> The code using Boost.Exception would look like:
>> typedef boost::error_info<
>> struct tag_archive_filename, std::string> archive_filename;
>> ...
>> try {
>> ifstream is(filename);
>> binary_archive ia(is);
>> my_data d;
>> ia >> d;
>> } catch (boost::exception& e) {
>> e << archive_filename(filename);
>> throw;
>> }
> lol - now you've thrown away all the information in archive_exception!

Nope. throw without an argument rethrows the
original exception object.

> Use this instead.
> try {
> ifstream is(filename);
> binary_archive ia(is);
> my_data d;
> ia >> d;
> } catch (boost::archive::exception& ae) {
> // assuming you love boost exception
> boost::exception e(ae);
> ae << archive_filename(filename);
> throw(ae);
> } catch(std::exception & se){
> // special sauce for standard library exceptions
> throw ...
> }
> Nothing in this requires any special help from boost::throw_exception.
> It's all in he user's program.

To make this work you have to enumerate
all the possible exception types that
you might have to deal with. You may not
even know all the possible exception types.
Also, knowing that you have something that
derives from std::exception isn't enough.
To preserve all information, you have to
know the full dynamic type of the exception.

>>> If you really like
>>> boost::exception
>>> your code when you eventually can eventually rethrow
>>> catch (std::exception e){
>>> }
>> This of course loses the original type of the exception.
> I don't think that's true. It's not clear to me from the documentation.
> I get this idea from looking at the code. Of course if it
> were true it would be huge blunder in the design of the library.

If you throw something with a static type
of std::exception, it's simply not possible
to know what its dynamic type is. A throw
with no argument can preserve the original
exception, but there's no way to use "throw;"
to inject Boost.Exception.

>>> How is this different from using std::exception ?
>> std::exception doesn't allow any addition annotation.
>> Using std::exception, there's simply no way to
>> add any additional information without either
>> a) Knowing the type of the original exception, or
>> b) Discarding all the type information of the original exception.
> A user can create an object at the catch site to add any information he
> wants. He can do this using boost exception if he wants or any other
> system he prefers. This doesn't require any thing special from the
> throw site. That is, there is no reason not to use anything but simple
> throw which of course is the original definition of boost::throw_exception.

You're ignoring my point. Would you mind
explaining how to avoid both (a) and (b)?
Or pick one and explain why you think it
isn't a problem? As I see it, (a) is extremely
verbose if there are multiple possible
exception types, and (b) can obviously lose
important information.

In Christ,
Steven Watanabe

Boost list run by bdawes at, gregod at, cpdaniel at, john at