
On Tue, Oct 12, 2010 at 7:59 PM, Peter Dimov <pdimov@pdimov.com> wrote:
Daniel Walker wrote:
But the coupling with Boost.Exception is only there to implement the strong exception safety guarantee of operator().
Your terminology is wrong. Both variants of operator() have the same exception safety; and even if they didn't, nobody uses "strong exception safety" to mean "throws an exception when such-and-so".
OK, I think there is a terminology problem here. I think we need to make a distinction between an "exception safety precondition" and a "call precondition" with respect to functions. A call precondition is a condition that must be met in order to call a function. An exception safety precondition is a condition that must be met in order to ensure that after a function has been called, during its execution, it conforms to an exception safety guarantee. Part of the requirements of boost::function is to account for differences between function pointers and function objects. A function object has no call precondition; i.e. a call to operator() cause operator() to execute. A function pointer does have a call precondition; i.e. a call to a function pointer only executes a function if the pointer is not null. In "promoting" function pointers to function objects, boost::function must transfer the call precondition from function pointers. To do this in an exception safe way, it must check whether the call precondition is met, otherwise it cannot offer a strong exception safety guarantee during the execution of boost::function::operator(). So, boost::function's precondition corresponds to a call precondition not an exception safety precondition. boost::function is always strong exception safe; i.e. boost::function invocation has no exception safety precondition. There are then two ways of looking at unsafe_function. You can say that it does not transfer the call precondition of function pointers in an exception safe way. Or you can say that it transfers the call precondition by making it an exception safety precondition, in which case unsafe_function is actually strong exception safe given the call precondition. So, using terminology that hopefully everyone can agree to, we can say that boost::function has no exception safety precondition (it is unconditionally strong exception safe), but with unsafe_function, the call precondition is an exception safety precondition.
The issue is not coupling with Boost.Exception, the issue is that the user has to supply a definition of boost::throw_exception when exceptions are disabled. This was true before there were Boost.Exception.
Well, I mean currently boost::throw_exception is part of Boost.Exception. So currently, from a user's perspective at least, boost::function is coupled with Boost.Exception. Daniel Walker