Date: Sat, 23 Aug 2025 06:58:47 +0100
> Look at this example:> ---------> {> int* p = new int(42);> int* const& to_p = p; // as a guideline> delete p; // if taken by reference an nullified> *p; // this will be a guaranteed runtime error> *to_p; // and all previous copies obey tooYou can’t do this last bit because you do not know where those references are.But if your original pointer outlives all these references, then it doesn't matter where they are.Tools like (&, const, volatile...etc), they have usage semantics behind them.So if your API uses a reference, you are conveying the idea that your variable will outlive its reference, If your API uses const, you're conveying the idea that no change is guaranteed....and so forth.> }> ---------> On top of that, basically we need just to add a guideline that mandate:> -All duplication of a pointer should be by reference if modifying, or const reference if not.Doing this would require allocating memory to hold the reference, and then having some way to manage the lifetime of that reference. At this point you have replaced raw pointers with handles, but handles have the same lifetime difficulties of the original pointer.That's a smart pointers job.The proposal revolves around the idea of single point of control.That is, no matter where you pass the reference, as soon as the control flow comes back to the scope of the original pointer, I will know if any of the users had freed the resource.{my_ptr = new T;someFnBy(&);someContainer.insetBy(&)...../// when back to this scopeif (my_ptr != nullptr) delete my_ptr;}> So it is guaranteed that if you free the memory using any of the references, all copies will be nullptr.> > So, is there any constraints to prevents this other than breaking old code?Fundamentally it does not work. Assuming that you are able to break older code, and take the performance and memory cost, you now need to ensure appropriate lifetime of the handle object, because those need to be allocated and released, and to handle |this| you need to be able to go from an arbitrary pointer back to a handle. Then to handle |this| you need to have a way to go from |this| to a handle, even though |this| may be a sub object, or other non-dynamically allocated object (stack variable, global, etc).There is no simple fix for lifetime safety in C or C++.—OliverActually it does work without breaking any code.You have to overload the delete operator in global scope.template <typename T>void delete(void*, T* &p){ delete p; p= nullptr;}And you do the same with the delete[ ].But because there is always a chance that some class will reimplement these operators, then the behavior is not uniform, unless the standard delete operator does the trick.
Received on 2025-08-23 05:58:58