Boost logo

Boost :

From: Matthew Herrmann (matthew.herrmann_at_[hidden])
Date: 2006-11-14 17:29:16


>
> Message: 5
> Date: Tue, 14 Nov 2006 20:38:43 +0200
> From: "Peter Dimov" <pdimov_at_[hidden]>
> Subject: Re: [boost] Review Request: Boost Exception
> To: <boost_at_[hidden]>
> Message-ID: <00ee01c7081c$1f94f230$6607a8c0_at_pdimov2>
> Content-Type: text/plain; format=flowed; charset="iso-8859-1";
> reply-type=original
>
> David Abrahams wrote:
>
>> > "Peter Dimov" <pdimov_at_[hidden]> writes:
>> >
>>
>>> >> David Abrahams wrote:
>>>
>>>> >>> "Peter Dimov" <pdimov_at_[hidden]> writes:
>>>> >>>
>>>>
>>>>> >>>> Moving the catch clause to a destructor doesn't seem an improvement
>>>>> >>>> to me.
>>>>>
>>>> >>>
>>>> >>> Using a catch clause to add information to a propagating exception
>>>> >>> feels syntactically heavy to me, but of course others may disagree.
>>>> >>> And it may also be that without language support, there's not
>>>> >>> really a good way to avoid that weight. I'm just expressing an
>>>> >>> aesthetic preference here.
>>>>
>>> >>
>>> >> Won't you need to prepare all the extra information even if nothing
>>> >> throws?
>>>
>> >
>> > No, you could do it lazily.
>>
>
> I'm afraid that I need to be shown an example in order to "get it". :-)
>

I think Mr Abrahams is referring to an idea similar to this: (please
ignore the class name, it is a placeholder only)

void read_file()
{
   boost::exception_info e(..., filename, current_pos, is_connected);
    ...
    e.success();
    return;
}

e.success() sets a flag to true, which prevents the generation of error
information when the object is destroyed. To remove the e.success(),
you'd need to detect whether the stack was being unwound due to an
exception or due to a natural return. This is where language support (or
compiler-dependent tricks) would be required. Nested exceptions
complicate that picture.

The other issue is how to handle return values cleanly. You could make
success() a pass-through function so you could handle return values with
a shorter syntax:

int sum(int a, int b)
{
   error_info e;
   ...
   return e.success(a+b);
}

template <typename T>
T& error_info::success(T& value)
{
    flag = true;
    return rhs;
}

(special care needed to avoid copying and to handle
references/temporaries etc). Ultimately, this approach is cleaner when
there are more exit points due to exceptions than from return
statements. Otherwise, you could forget to call success() at one of the
return sites and hit a performance issue as it generates the exception info.

Regards,
Matthew Herrmann


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