C++ Logo

std-proposals

Advanced search

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

From: Tiago Freire <tmiguelf_at_[hidden]>
Date: Mon, 17 Feb 2025 18:44:40 +0000
I think that if you are willing to work within those limitation it could work. I get it, the idea doesn't seem unsound to me.

If you want to give the proposal it's best chance of success, it is best if you provide an easy to use sample implementation of it, and also a killer example of a use case for this feature where this type of pointer does best and show how other pointers aren't suitable for the job. And make sure to highlight those tradeoffs.

Not to try and be discouraging, but even so it will be hard to get this accepted, if it had been anything else it might have been easier, but people will be naturally apprehensive to a new kind of smart pointer and very concerned on its safety aspect. It's expected that the audience could be split or even negative on the matter.

And note that it isn't just enough to demonstrate that the idea is sound, you have to convince why this feature should be part of the standard and not just be a standalone third-party library.
You have to be prepared for the fact that the proposal will live as an external library for a while until it gathers enough user experience, and even then it is not certain.

I wish you good luck with it.





________________________________
From: Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf of JOHN MORRISON via Std-Proposals <std-proposals_at_[hidden]>
Sent: Monday, February 17, 2025 6:26:42 PM
To: std-proposals_at_[hidden] <std-proposals_at_[hidden]>
Cc: JOHN MORRISON <inglesflamenco_at_[hidden]>
Subject: [std-proposals] A non-owning but self zeroing smart pointer for single ownership

Responding to Tiago Freire
Hi Tiago,

You wrote:
I don’t think it needs to compromise on single-ownership.
I can see 2 solutions for this:
1. Give up on thread safety. The owning pointer only takes the responsibility to notify any weak pointer constructed from it. It works, just not in a multithreaded setup.
2. Locking the destructor of an owning pointer if a weak pointer acquires some sort of lock. Can lead to a dead lock. Would definitely be the most dangerous of the bunch.
In either case it requires an intermediate object to connect between the owning pointer and the weak pointer such that communication can take place, you can’t do it with a regular unique_ptr.

This is exactly how I see it. You either accept that singly owned objects cannot be safely visible to multiple threads as we have always done or you put a lock on destruction when you make use of ptr_to_unique.

The second will ensure that single ownership destructors don't get called out of sequence but the potential for deadlock with that lock is a bit scary. It will require more overhead and if a background thread holds it locked for a long time while working on it, I could end up with my GUI thread frozen and a very frustrated user. I think it would be more of a specialist solution that you would construct and use when needed with the proviso that you never hold on to that lock for very long.

The first which is encapsulated by the proposed ptr_to_unique doesn't mean not worrying about or ignoring thread safety. You worry about it in the same way that you always have done. Data that is visible to multiple threads must have shared ownership and singly owned objects must never be visible to other threads. Following those rules, as we have always done, will ensure that you never hold a ptr_to_unique to a unique_ptr that is exposed to the actions of another thread and the ptr_to_uniques you have will work safely. It does use an intermediate object, a reference counted control block, and it works with a regular unique_ptr declared with a deleter hook.

You also wrote:
It could work in theory, but given the compromises, it’s already rare that you get to use weak_ptr, it could be hard to find a set of conditions where you would use it but also couldn’t just use a shared_ptr

I suspect that the low use of weak_ptr might be largely down to laziness and the perception that its only use is to “break cycles”. A lot of shared_ptrs should probably be weak_ptr but it is a lot more trouble to code. Things still work but the proliferation of shared_ptrs can result in a lot of unintended memory retention. Doing this effectively builds a prompt but slightly leaky garbage collector.

The proposed ptr_to_unique is intended to help with the many things that can happen in a single thread with single ownership. Below is an extract from an earlier post:

My need for this arose in the development of event driven GUI applications which are a form of cooperative multitasking all running in one thread. A lot of lifetimes can come and go but all the event handlers that you write are running in the same thread. Typically I will be displaying a polymorphic collection of objects and may run a procedure to pick out some that require special attention. I don't want to run that procedure every time the screen is repainted so I hold pointers to those objects. If the pointer is still valid, I use it. If not then its do nothing or run the procedure again. It was a necessary optimisation to prevent screen lag and I used to write a lot of very intrusive and fragile spaghetti code to make sure that those pointers were zeroed if their pointee was deleted.
And you wrote:
When you delete that owned object, do you actually need it to be deleted at that exact moment?

The answer is absolutely yes. This is single ownership design and RAII. When I delete an object from a collection I want it gone and its destructor called now. I don't want it living on as a phantom object being kept alive by some forgotten shared reference somewhere and its destructor called at some indeterminate time in the future.




Received on 2025-02-17 18:44:43