Boost logo

Boost :

Subject: Re: [boost] Looking for thoughts on a new smart pointer:shared_ptr_nonnull
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2013-10-10 20:19:15


On 10/11/2013 11:50 AM, Quoth Nevin Liber:
> If everything is good, where did the bad null pointer come from?? More
> likely than not it is due to another (undetected) broken invariant.

Possibly, but it's more likely that it came from an unchecked failure
condition (by which I mean that a particular method can intentionally
return null sometimes, but the developer forgot to check for that).
Developers are in general notoriously bad at remembering to do the error
checking.

> It is up to the designer of the library to determine if passing parameters
> that make it impossible to set up the class invariant is reasonable or
> not. If it is reasonable, it is part of the contract, and no problem.

If it is reasonably possible for a method to detect that its input would
cause it to violate the class invariant, then it should report that
failure in a defined way without UB. The only defined way that a
constructor can fail is to throw an exception. Therefore, if it is
feasible for a constructor to detect that it has been given invalid
input, it should throw an exception.

The only time UB should be permissible is if it is not feasible to
validate the input, or there is some compelling (and documented)
performance reason to skip the validation. Otherwise the library
designer is just being lazy.

Given that we're talking about a simple null check here, there's no
excuse to skip it.

> If it was okay with it being null, why did it pass it to the non-null smart
> pointer?

You are referring to two different things as if they were the same. The
"it" being ok with the pointer being null is the code further up the
callstack (destructors via stack unwinding) while the "it" with the bug
is the immediate caller of the non-null pointer that didn't validate the
pointer-that-could-be-null after obtaining it from
somewhere-that-could-be-null-because-it-didn't-use-a-not-null-pointer.

And because the caller didn't think about it.

> Could you please show us your universal catch handler that handles every
> possible programming error w/o aborting, including corruption that might
> happen during the stack unwinding?

Could you show how stack unwinding could possibly cause corruption?
There's no reason for it to do so, certainly not merely in the face of a
bug that led to a pointer being unexpectedly null.

Sure, it's possible for there to be lots of bugs, and you're never going
to have something that can comprehensively resolve everything. But
buggy destructors are something that you tend to notice pretty early on
during development.

As to whether you can recover, as I said before it's very
program-specific and you can't give something that would work
generically. But you're more likely to be able to successfully recover
in a program that operates on independent requests (eg. webserver) or
that is specifically designed to track actions for possible rollback
(eg. database) or something highly modular with subsystems that can be
destroyed and recreated. It's probably not going to be feasible in
something that has a lot of mutable shared state.


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