Subject: Re: [boost] Looking for thoughts on a new smart pointer: shared_ptr_nonnull
From: Julian Gonggrijp (j.gonggrijp_at_[hidden])
Date: 2013-10-07 06:47:06
Gavin Lambert wrote:
> On 10/7/2013 6:56 PM, Quoth Matt Calabrese:
>> No, it's not thrown before UB occurs. By having a function with
>> preconditions and calling that function with values that don't meet those
>> preconditions, you have undefined behavior. If you want specified behavior,
>> then it's not a precondition. That said, I've already also explained why it
>> should be a precondition. Please, let's not turn this into a vector at().
> Can you please restate why you think it should be a precondition? I've reread the thread and all I can find is "Initializing the object by
> passing a null pointer should be UB since it is a clear violation of the
> constructor's assumed precondition (don't pass a null pointer)" which is a statement with an assumption, not an explanation. (You go on to quite some lengths about why throwing is bad for preconditions, but not why you think it should be a precondition in the first place.)
> My argument is that it should be an explicitly-validated parameter, not an assumed-valid-via-precondition one.
> And again, we're only talking about the constructor here. I have no problem with operator-> etc assuming the invariant that the internal pointer is non-null, or that anything that accepts an already-constructed pointer can assume that the pointer is non-null. I just don't agree that this applies to the constructor.
While I'm not Matt Calabrese, I think I can restate why it should be a
precondition *especially* on the constructor. The entire point of the
proposed non-null pointers is to guarantee that the pointer is not
null, so that receiving functions and storing objects can assume that
it is not null. If you zero-initialize a pointer whose very purpose is
not to be null, you defeat the purpose of its existence.
Note how this is entirely analogous to std::sort, whose purpose is to
perform an operation on a valid range. If you pass an invalid range,
you defeat the purpose of the existence of the algorithm. This is why
such algorithms have the precondition that you pass a valid range,
IOW, that you only use them for what they were meant to be used for.
Also note that a developer has the full power to decide whether they
call std::sort with a valid range or not. If for whatever reason there
may be any uncertainty about the validity of the iterators passed to
the algorithm, it is possible to redesign the program to remove that
uncertainty. Similarly, a developer can design their program to
guarantee with 100% certainty that non-null pointers will never be
zero-initialized. The simplest way to do that is by initializing all
non-null pointers with make_shared or another non-null pointer.