lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Non-null smart pointer (was: Reference lifetime extension)


From: Vadim Zeitlin
Subject: Re: [lmi] Non-null smart pointer (was: Reference lifetime extension)
Date: Sat, 13 Oct 2018 15:31:54 +0200

On Fri, 12 Oct 2018 23:18:31 +0000 Greg Chicares <address@hidden> wrote:

GC> On 10/12/18 11:06 AM, Vadim Zeitlin wrote:
[...]
GC> >  The core guidelines recommend using not_null<T*> which should appeal to
GC> > you as it avoids any mention of smart pointers (which still need to own 
the
GC> > object, however). I don't like it that much because if you accept the
GC> > guideline that functions not changing ownership should accept pointers 
only
GC> > as T*, it means having a lot of .get() calls in the code, but maybe you
GC> > wouldn't mind it that much.
GC> 
GC> I can't really say, without seeing how obtrusive it would be. And it
GC> seems really difficult to find usage examples online; is that because
GC> it's not actually in broad use?

 I'd guess not yet, it's relatively new.

GC> >  Finally, there is a natural idea of using not_null<unique_ptr<T>> but
GC> > there seems to be a problem with this in the most widely implementation of
GC> > not_null, see https://github.com/Microsoft/GSL/issues/89 and the proposed
GC> > fix at https://github.com/Microsoft/GSL/pull/675
GC> 
GC> It sounds like an attractive idea. But if I'm reading this correctly,
GC> issue 89, opened 2015-09, is a pretty shocking shortcoming; and PR 675
GC> was proposed 2018-05, but hasn't been accepted or rejected yet. I'm led
GC> to question whether the library is actively maintained, or even sound;
GC> but perhaps designing this particular library facility to embrace smart
GC> pointers is just surpassingly difficult.

 I think it is actively maintained, but they postponed dealing with this
particular issue hoping that C++ core guidelines themselves would be
updated to address this issue (which hasn't happened yet).

GC> > but perhaps we could write our own not_null<unique_ptr<T>> using the
GC> > information above (and yes, I'd be willing to do this, please let me
GC> > know if I should).
GC> 
GC> That's an intriguing idea. How would you design it? I see at least
GC> two ways. One way (1) is to test whether a pointer is null whenever
GC> it's dereferenced; another (2) is to test whether it would be made
GC> null whenever it's initialized or assigned. But std::unique_ptr is
GC> movable-from, so it wants to be nullable: is that the crucial
GC> problem? and if so, is the solution to use a nonmovable scoped_ptr,
GC> and avoid move semantics?

 We want to have a smart pointer that can be returned from a function, so
it must be either copyable or movable. And we also want it to be owning,
which means it can't be copyable (unless you impose the use of reference
counting, i.e. make it shared_ptr<> instead of unique_ptr<>), so it has to
be movable.

GC> Either way, I guess we'd be transforming every raw pointer into a new
GC> kind of smart pointer. I've just experienced another konsole krash,
GC> so I kan't kopy kode examples with the X klipboard, but for example
GC> there's a 'wxPdfDocument* whatever' line somewhere now; would we
GC> have to wrap that, and then explicitly get() it prior to each use?

 Yes, this would presumably become "not_null<wxPdfDocument*> whatever" and
you'd have to use get() to retrieve the raw pointer. OTOH, as it is not
supposed to be null, we shouldn't even need to use the pointer, only the
reference, and this can be obtained via operator*(), just as with the raw
pointer, so there would be no syntactic overhead.

GC> (I should think we'd automate dereferencing by defining operator.()
GC> and operator->(), but if we want to pass a pointer (say, to pass a
GC> wxWindow* to a wx function), then we'd need get() each time, or,
GC> equivalently, operator()()).

 wxWidgets is problematic because it requires passing pointers everywhere
and while in most places these pointers must be non-null, sometimes they
may be null. I'm afraid there is no good solution here, other than
providing a better API.

GC> Wouldn't either (1) or (2) alone suffice?

 Unfortunately no. We want to do (2) in order to detect the errors (as
assigning NULL to a not_null_ptr is an error) as early as possible. But we
also have to do (1) because we can't statically prevent the use of a
moved-from object. This is definitely annoying but, as with wxWidgets API
above, this is not something that can be solved without changing the
language itself. Of course, there are ongoing efforts to do just this, see
lifetime warnings work covered in a recent talk by Herb Sutter (see
https://www.youtube.com/watch?v=80BZxujhY38 or, if you'd rather read than
watch, 
https://github.com/CppCon/CppCon2018/raw/master/Keynotes/thoughts_on_a_more_powerful_and_simpler_cpp/thoughts_on_a_more_powerful_and_simpler_cpp__herb_sutter__cppcon_2018.pdf)
but this doesn't help us today.

 To summarize, we can have not_null_ptr<> satisfying our needs, but with
some run-time overhead. In practice I think gcc should optimize away the
checks in most cases, but probably not always.

 Regards,
VZ


reply via email to

[Prev in Thread] Current Thread [Next in Thread]