Boost logo

Boost :

Subject: Re: [boost] Looking for thoughts on a new smart pointer: shared_ptr_nonnull
From: Julian Gonggrijp (j.gonggrijp_at_[hidden])
Date: 2013-10-11 10:29:02


Thorsten Ottosen wrote:

> ""17.6.4.11 Requires paragraph [res.on.required]
>
> Violation of the preconditions specified in a function’s
> Requires:
> paragraph results in undefined behavior
> unless the function’s
> Throws:
> paragraph specifies throwing an exception when the precondition is violated."

I think you are right about this: IF a function throws when its
precondition is violated, then the resulting behaviour is defined. I
previously replied with +1 to Nevin when he claimed the opposite
(among other things); I admit not studying that bit carefully enough.

This is however tangential to the question whether a function *should*
throw when its precondition is violated. Herb Sutter wrote a piece on
error handling [1] which I think is insightful. Herb Sutter states,
and I think I agree, that it is the responsibility of the caller to
ensure that preconditions are met; hence it is also the responsibility
of the caller to report an error when it cannot meet the preconditions
of the callee (and it cannot avoid the call). Of course you can do an
additional check inside the callee, but that check should be
considered to be redundant and on violation the real error is in the
caller, not in the callee.

Herb Sutter wrote:

> The code that could cause an error is responsible for detecting and
> reporting the error. In particular, this means that the caller is
> responsible for detecting and reporting a to-be-called function's
> parameter precondition violations. If the caller fails to do so, it is
> a programming mistake; therefore, when the parameter precondition
> violation is detected inside the called function, it can be dealt with
> using an assertion.

I recommend reading all of Sutter's piece.

I think the discussion so far has concerned several points, the first
three of which can now be closed as far as I can tell:

* Does violating a function's precondition result in undefined
behaviour?
~ No if it throws when it detects the violation, yes otherwise.

* Should a function throw when its precondition is violated?
~ Going with Herb Sutter: no, but the caller should throw when it is
about to violate it.
(In the case of shared_ptr_non_null, the caller could be a factory
function or a wrapper with the specific purpose of checking for null.)

* Does checking for null add overhead in the constructor of
shared_ptr_non_null?
~ Not much compared to memory allocation, but it is still redundant IF
not passing null is a precondition (if you agree with Herb Sutter).

* Should not passing null be a precondition on the constructor of
shared_ptr_non_null?
~ Personally I think it should, because there is no sensible way to
construct a shared_ptr_non_null from a nullptr. In the end, it will
be up to the library designer (Luke Bradford) to decide.

Note that if the factory function allocates the pointer with a
throwing allocator, the nullptr check and corresponding error
reporting is already built-in.

-Julian

[1] http://www.drdobbs.com/when-and-how-to-use-exceptions/184401836


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