Subject: Re: [boost] [function] function wrapping with no exception safetyguarantee
From: Stewart, Robert (Robert.Stewart_at_[hidden])
Date: 2010-10-21 07:33:17
Daniel Walker wrote:
> Nevin Liber wrote:
> > Daniel Walker wrote:
> >> If the call precondition is not met and boost::function::operator()
> >> attempts to call the target function, then the program could crash.
> > In the case of raw function pointers (either NULL or uninitialized),
> > from that point on the program can do whatever the heck it wants to
> > do, since it is now in the realm of undefined behavior. Heck, you
> > can no longer guarantee that *any* object in your system is still in
> > a consistent, let alone correct state.
> True, and in the worst case scenario, the program could crash.
No. The worst case scenario is that the program continues to run and does all sorts of wrong things like sending market orders for too many stocks at an enormous price or overdoses a patient.
> >> Instead, under the current implementation,
> >> boost::function::operator() checks the call precondition
> > What call precondition? It is perfectly legitimate to call
> > operator() on a default constructed boost::function; it has
> > well defined semantics.
> In order to call a function using boost::function, the following
> precondition must be met: boost::function must be non-empty. The
Not true. That is not a precondition. In order to successfully invoke a function, there must be a function to invoke, but boost::function's function call operator behaves as documented when there is no function.
By contrast, a precondition is a condition that the caller must satisfy in order for the called function to behave as documented. Violating the precondition leaves the function's behavior wide open.
> reason that operator() has well defined semantics, even when called on
> a default constructed boost::function, is that operator() checks the
> call precondition before attempting to dispatch a target function.
That is a case of behaving as documented. The operator is *not* checking a precondition. It is merely deciding which of two alternatives to pursue based upon the state of the object.
> > For a parallel, look at std::vector at() vs. operator. at()
> > has no precondition on the index passed to it, while operator
> > requires it to be in the range [0..size()).
> > Would you say that operator doesn't have the strong
> > exception safety guarantee?
> On the precondition that the vector is not empty, then operator has
> a strong exception safety guarantee. On the other hand, at() is
> unconditionally strong exception safe. It's just a matter of stating
> what the preconditions are for exception safety. boost::function has
> no exception safety precondition, unsafe_function has one exception
> safety precondition -- the call precondition.
That isn't an "exception safety precondition" as you call it. It is a precondition. If you call a function without satisfying its preconditions, the function can behave in any way. The caller violated the precondition so the function is not obligated to behave in any rational manner, much less in keeping with its documentation.
If the caller satisfies the precondition, then the function is obligated to behave as documented, including meeting any documented exception guarantee. In the case of Boost.Function, it's:
> >> either completes successfully or throws an exception with the
> >> program state maintained, which conforms to our running
> >> definition of a strong exception safety guarantee.
I hope this helps, at least by clarifying terminology.
Rob Stewart robert.stewart_at_[hidden]
Software Engineer, Core Software using std::disclaimer;
Susquehanna International Group, LLP http://www.sig.com
IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk