
On Mon, Oct 11, 2010 at 3:20 PM, Emil Dotchevski <emil@revergestudios.com> wrote:
On Mon, Oct 11, 2010 at 11:53 AM, Daniel Walker <daniel.j.walker@gmail.com> wrote:
On Mon, Oct 11, 2010 at 2:45 PM, Daniel Walker <daniel.j.walker@gmail.com> wrote:
On Mon, Oct 11, 2010 at 2:05 PM, Emil Dotchevski <emil@revergestudios.com> wrote:
On Mon, Oct 11, 2010 at 10:45 AM, Daniel Walker <daniel.j.walker@gmail.com> wrote:
On Mon, Oct 11, 2010 at 2:49 AM, Nevin Liber <nevin@eviloverlord.com> wrote:
On 11 October 2010 00:01, Emil Dotchevski <emil@revergestudios.com> wrote: > On Sat, Oct 9, 2010 at 12:38 PM, Daniel Walker > <daniel.j.walker@gmail.com> wrote: >> Finally, there have been suggestions to alter boost::function's >> exception safety guarantee directly through either policies or >> constructor options. > > We used to have an Allocator parameter to the boost::function template > and it was removed (just in time for this change to also be reflected > in C++0x) to reduce coupling.
So what exactly is the proposed behavior if the function object cannot fit in the small object optimization space of unsafe_function and the allocation fails?
As proposed, unsafe_function has the same semantics as boost::function with one (and only one) exception: the behavior of operator() is undefined when it has no target.
If that was the only motivation, you could just disable exception handling, and then define:
namespace boost { void throw_exception( std::exception const & ) { assert(0); } }
Correct. But users have complained about this, which is exactly the motivation for unsafe_function. It works out-of-the-box in RTTI-free environments with no dependency on boost::throw_exception. It's a simple problem really.
P.S. Sorry I spoke to soon. That's not exactly correct. A user could do what you describe, but boost::function could not, since that would change its exception safety guarantee; i.e. it would no longer throw (or call a user definable function) when it had no target.
This is not exception safety issue, it is a choice between defined and undefined behavior.
A strong exception safety guarantee is a defined behavior. unsafe_function removes that guarantee and leaves its behavior undefined when its preconditions aren't met; namely, it dereferences a null pointer, which has an undefined (and undefinable) behavior.
Undefined behavior is desirable when there are performance or portability problems with defining a behavior. No such problems exist with the current boost::function semantics. You can't both want undefined behavior and be against any particular behavior, such as throwing an exception or calling a function.
boost::function's behavior is defined in all circumstance, even when it's preconditions are met. That's a necessary requirement of a strong exception safety guarantee. However, some users have complained about the definitions. From listening, I believe they would prefer a function wrapper that behaved more like a function pointer when its preconditions are not met; i.e. they do not want RTTI or boost::throw_exception. The simplest way to establish this is to adopt no exception safety guarantee. (I am trying to follow Dave's exception safety paper by the way. I linked to it in the documentation in the patch, to provide users some background.)
The only viewpoint from which this discussion makes sense to me is that it might be beneficial to remove the coupling between boost/function.hpp and boost/throw_exception.hpp, <snip>
Yes, that's exactly the way you should look at it. However, the coupling is a good thing for boost::function. If you're going to offer a strong exception safety guarantee, Boost.Exception is a good way to implement it. So, for one group of users, boost::function is perfect as is. But one size does not fit all. Another group of users, would like a function wrapper without coupling Boost.Exception, and indeed, without an exception safety guarantee. unsafe_function address the demands of this second group of users. Daniel Walker