Boost logo

Boost :

Subject: Re: [boost] [function] function wrapping with no exceptionsafetyguarantee
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2010-10-12 13:48:37


On Tue, Oct 12, 2010 at 3:44 AM, David Abrahams <dave_at_[hidden]> wrote:
> At Mon, 11 Oct 2010 14:19:31 -0400,
> Daniel Walker wrote:
>>
>> On Mon, Oct 11, 2010 at 10:43 AM, Domagoj Saric
>> <domagoj.saric_at_[hidden]> wrote:
>> >
>> > "Daniel Walker" <daniel.j.walker_at_[hidden]> wrote in message
>> > news:AANLkTikdt4Cx9QcqeUX=SZ9rB8uqrmaahLpfMgxtEkTv_at_mail.gmail.com...
>> >
>> >> I have to say that I don't find the idea of gutting the current
>> >> implementation to be particularly attractive. Boost.Function is
>> >> already proven and familiar, and there's more we can still do with it.
>> >
>> > We can do more with it w/o 'gutting' it? I'm sorry I do not understand why
>> > unsafe_function does not constitute 'gutting' while my changes do...note
>> > that 'my' function requires no macro or a different name and is backwards
>> > compatible with existing code (it only needs to be recompiled)...
>>
>> My patch is very simple, and there are very few changes to the
>> existing code. It uses the existing preprocessor metaprogramming
>> infrastructure of Boost.Function to generate the same implementation
>> code for both boost::function and unsafe_function with one small
>> exception: The guarantee that operator() throws when it has no target
>> is removed from unsafe_function. So, the vast majority of the
>> implementation (type-erasure management, etc.) is unchanged.
>
> I'm sorry if I missed something important here, but has everybody
> really considered the consequences of Peter Dimov's post, where he
> wrote:
>
>> This example implies that unsafe_function is inherently more
>> efficient, but this need not be so. An empty function may point to
>> throw_bad_function_call instead of NULL.
>
> One could swap out throw_bad_function_call for any behavior you like.

unsafe_function is not inherently more efficient. In optimized object
code (gcc -02 or MSVC Release mode) the difference between invoking
unsafe_function or boost::function is minuscule (on the order of
hundreds of picoseconds). Peter's post similarly relies on removing
the NULL pointer check for performance gains. This may be a good idea
or it may be a case of premature optimization; whether or not it
improves performance depends on the compiler's optimization. But
either way, efficiency is tangential to the issue of boost::function's
dependency on Boost.Exception.

Also, swapping out throw_bad_function call does not directly address
the boost::function/Boost.Exception coupling issue. If boost::function
is going to offer a strong exception safety guarantee, then I believe
Boost.Exception is the best way to implement that guarantee, no matter
how boost::function gets around to calling boost::throw_exception. (I
also think boost::function should continue to offer the strong
guarantee.) But some users are asking for a function object wrapper
that is not coupled with Boost.Exception. The simplest way to decouple
them is to provide a function object wrapper without the strong
exception safety guarantee.

>
>> > <snip>
>> > However, here http://lists.boost.org/Archives/boost/2010/01/160908.php you
>> > can see results that show a measurable difference when function<> is
>> > configured to mark itself as nothrow...
>>
>> The goal of unsafe_function is not to provide a wrapper that doesn't
>> throw, but to provide a wrapper with no exception safety guarantee.
>
> If that's *really* its goal, unsafe_function is strictly unneeded.
> boost::function already satisfies all your requirements (and more).

boost::function always provides a strong exception safety guarantee.
Specifically, if its preconditions are not met, it calls
boost::throw_exception. This is true whether or not the system has
RTTI. This is great for some users, but others have asked for a
function object wrapper that does not call boost::throw_exception. A
simple way to meet this requirement is to provide a function object
wrapper that is exception unsafe, like a typical function pointer for
example, and that is what unsafe_function does.

>  I think if you're looking to supply motivation for unsafe_function,
> you'll need to describe the goal differently. ;-)

How about this. Typically, function pointers have no RTTI dependency
(and no dependency on Boost.Exception) and are exception unsafe.
unsafe_function is a function object wrapper that behaves more like a
function pointer with respect to exception safety.

Daniel Walker


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