Subject: Re: [boost] [function] function wrapping with no exception safetyguarantee
From: Stewart, Robert (Robert.Stewart_at_[hidden])
Date: 2010-10-22 07:48:48
Daniel Walker wrote:
> Rob Stewart wrote:
> > 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.
> I think in the case of function wrappers it helps to make a
> distinction between what I call a "call precondition" and an
> "exception safety precondition." A call precondition is a
> condition that must be met in order to invoke a function. One
> example would be, as you put it, "there must be a function to
> invoke;" i.e. the wrapper has to be assigned a target.
That example is valid only if the design and documentation of the wrapper establish that as a precondition. It does not apply to boost::function.
> Or here's a simpler example: if you intend to invoke a function
> through a function pointer, a call precondition is that the
> function pointer is not null.
Yes. That precondition is given by the language. Violating it results in UB.
> An exception safety precondition applies after a function has been
> called and is running. And I like your wording, it is "a condition
> that the caller must satisfy in order for the called function to
> behave as documented" with respect to exception safety.
If the caller must establish that condition before invoking the function, then it is a precondition, pure and simple. Violating a precondition leaves the result wide open. In the case of boost::function, there is no such precondition. If invoked without a target, boost::function throws an exception. There's nothing special in that. It is documented behavior. The caller met the preconditions, invoked the boost::function object, that object found no target, and it threw an exception, all as expected.
> I think the reason the distinction is important is that
> function objects do not normally have call preconditions;
> i.e. the function is always there, and when operator() is
> invoked, control is passed to the function.
This is the case for boost::function except that there's an additional state permitted: the target may not exist and the result is an exception.
> With function wrappers, however, there is a level of
> indirection. When a function wrapper is invoked, control is not
> instantly passed to the wrapped function. This gives rise to
> some trade-offs. With boost::function, the call precondition is
> handled transparently with respect to strong exception safety
> such that calling a wrapped function is the same as calling the
> function directly: Either an exception will be thrown or the
> function will complete successfully given the target function's
> exception safety preconditions.
I hope Emil and I have helped you to understand that this is simply wrong. boost::function will throw an exception due to no target, or will invoke the target. There is nothing special in that and no precondition applies. What happens upon calling the target is the responsibility of boost::function's caller and the target; it is no different than invoking the target directly.
> With unsafe_function, the call precondition is an _additional_
> exception safety precondition, and so, unlike boost::function,
> its behavior is not documented (or defined) when the call
> precondition is not met.
unsafe_function's function call operator has a precondition that the target exists. Calling it without a target results in UB. Nothing else matters after that.
The distinction between boost::function and unsafe_function is that the latter's function call operator has a precondition that the target exists while the former's doesn't.
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