C++ Logo

std-proposals

Advanced search

Re: [std-proposals] A non-owning but self zeroing smart pointer for single ownership

From: Jeremy Rifkin <rifkin.jer_at_[hidden]>
Date: Sun, 23 Feb 2025 10:43:42 -0600
> which not only makes it difficult to follow the conversation textually,
but it confuses mail programs

+1, just FYI John every time you reply it's appearing as a new thread in
gmail.

[image: image.png]


On Sun, Feb 23, 2025 at 10:33 AM Jason McKesson via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Sat, Feb 22, 2025 at 6:07 PM JOHN MORRISON via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >
> > This is a long post so I have split it into sections so you don't get
> lost reading it.
> >
> >
> >
> ---------------------------------------------------------------------------------------------------------------------------------------------
> > Who has conflicting design goals? The proposed ptr_to_unique or our
> criteria for judging if something is acceptable?
> >
> ---------------------------------------------------------------------------------------------------------------------------------------------
> >
> > C++ is an enabling language (I would call it an engineer's language)
> that lets you construct anything including the means to shoot yourself in
> the foot or blow your head off. It generally does not a reject a useful
> feature just because a way can be found of using it wrongly. Although we
> may use the type system to constrain its use, it has always been the policy
> that there is no obligation that a feature must come with all the means to
> prevent its incorrect use. It has always been considered too big an ask
> that is likely to burden or compromise well formed code or even be
> impossible to achieve.
> >
> > However the language is now at a crossroads where there is an
> existential imperative to reduce its exposure to undefined behaviour caused
> by coding errors. This impacts on the above policy and has started to
> produce conflicting criteria in determining if a feature is good to use.
> Some cases of undetected 'ill formed code' have caused a lot of trouble so
> now there is a sense that a new feature perhaps should do more to prevent
> its incorrect use. This is a sense rather than a criteria or policy but it
> is at play and produces a new perspective.
> >
> > This crossroads puts the proposed ptr_to_unique in the cross hairs of
> both perspectives and they are conflicting. It isn't ptr_to_unique that
> has conflicting design goals, it is our criteria for judging its acceptance.
> >
> > According to the traditional approach, ptr_to_unique is acceptable
> because it has a large domain of correct use and incorrect use would be
> 'ill formed code'. Burdening it with thread checking just in case it is
> used incorrectly would be considered an abomination where you are paying
> for something that good code will never use.
> >
> > However we now feel a need to reduce the opportunities for ill formed
> code to be written undetected and certainly worry about introducing new
> ones. The proposed ptr_to_unique is new, it is a smart pointer and ill
> formed code can be written with it. So naturally that triggers concerns
> from this new perspective. To address those concerns I have provided thread
> checking to catch ill formed code at run time but this sorely offends the
> traditional perspective.
>
> I don't really know what any of this preamble is in response to. You
> seem to refuse to reply directly to specific e-mails, which not only
> makes it difficult to follow the conversation textually, but it
> confuses mail programs (Consider how this thread is presented here:
> https://lists.isocpp.org/std-proposals/2025/02/index.php It looks
> like you are replying to yourself a lot). It all ultimately feels like
> it's out of left field.
>
> But there is also a history of C++ development that is being ignored.
> For example:
>
> > It generally does not a reject a useful feature just because a way can
> be found of using it wrongly.
>
> So... why is `shared_ptr` sharable with threads by default? It adds
> overhead to the type, and there are certainly many scenarios where
> sharing across threads isn't necessary. So why burden the main
> shared_ptr type with this overhead instead of adding two types?
>
> Because safety is *always* something that should be considered.
>
> Safety is the reason `unique_ptr` and move semantics exist in the
> first place. It's the reason members can be declared `private`. It's
> the reason constructors and destructors exist, along with the various
> elements of the object model.
>
> C++ has *always* been in tension between safety and utility.
> Presenting this notion as if this is some new-fangled paradigm is just
> incorrect.
>
> Making threading a first-class citizen of the language means that the
> threading interactions of everything added to the language ought to be
> considered. And adding a feature that is actively hostile to threaded
> use is... a tall ask.
>
> From a behavioral standpoint, your `ptr_to_unique` is not a pointer.
> Its mechanics are more akin to a reference to a `unique_ptr`, similar
> to `reference_wrapper`. And reference types like `reference_wrapper`
> are inherently dangerous tools. That's not to say that we can't use
> reference types, where appropriate. Types like `function_ref` have
> been added because their utility outweighs their safety.
>
> The main issue I have with this type is that its reference mechanics
> are unsafe in a different way from other reference types.
>
> `function_ref` cannot work if the object it references has been
> destroyed. But this form of breakage is threading-agnostic. It doesn't
> matter if that destruction happened on a different thread; the object
> is broken either way. That is, reference types are just as dangerous
> single-threaded as they are multi-threaded (obviously threading allows
> for more *potential* for problems).
>
> Your `ptr_to_unique` reference *does* work if the object it references
> has been destroyed... sometimes. And that's the problem. Your type
> explicitly singles out threading in a way that general reference types
> *don't*. Yours works if the lifetime of the referenced object ends, so
> long as that happened on this same thread.
>
> That is a very different paradigm, and I cannot think of a type in C++
> that behaves that way. Iterators are invalid if the range they contain
> has been destroyed; it doesn't matter if that happened on this thread
> or a different one. `reference_wrapper` doesn't work if the thing it
> references is destroyed regardless of threading. `weak_ptr` works
> regardless of where the destruction happens. Etc. I don't know of a
> case where a reference type works with a destroyed object, but only if
> it was destroyed in this thread.
>
> So what we have in this `ptr_to_unique` is a type with extremely niche
> functionality (ie: most people won't be familiar with it) coupled with
> being brittle in a way that is unique in the C++ standard library.
>
> So if I'm extracting some code into another thread (possibly by just
> calling it from a coroutine), and I do a code-review to look for
> problems, it is very likely that I won't look up the documentation for
> this specific object. I see that it's being held by value, which is
> usually a sign that it can work across threads. I see that it is
> accessing a pointer stored in that object, but I also see from the API
> that it checks if the pointer is valid. So from a first-pass visual
> inspection, this ought to work.
>
> That fragility coupled with its niche utility makes me feel that it's
> not something that needs to be a standard library type.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2025-02-23 16:43:57