Date: Sun, 24 Aug 2025 21:25:50 +0100
Hi,HiProblems with this proposal:- what if pointer is a constant? Not _pointing to_ a constant, but _is itself a_ constant.It won't bind, a '&' cannot bind to a 'const&'....- Even if you delete an object, it is still valid to make historical comparisons between pointers _that existed at the same time_. E.g. if we are aware that p and q were both T* and existed at the same time, p==q tells you whether the two pointers were pointing the same object. This is valid _even after either or both objects are deleted_. So this change wouldn’t be compatible with current code.With this proposal, if either is deleted it will be nullptr and the equality will fail.With that said, _technically_ we could make `delete p` return a reference to p and thus `(delete p) = nullptr;` would both do what you say and be somewhat less surprising, albeit don’t consider this as something I myself would propose.That will be a real code breaker, wherever you have 'delete p', you have to change it to 'p = delete p', Where with this proposal you won't change a thing.Thanks,You are welcome.-lorroOn 23 Aug 2025, at 11:41, Oliver Hunt via Std-Proposals <std-proposals_at_[hidden]> wrote:On Aug 23, 2025, at 2:20 AM, organicoman <organicoman_at_[hidden]> wrote:Use after free, double free...etc will be more like to be caught in code{ m_ptr = new T; // if all the following take m_ptr by reference inspect_maybe_free(m_ptr); transform_maybe_free(m_ptr); maybe_free(m_ptr); // i can detect if delete was called before. if(m_ptr) delete m_ptr;}With the current implementation, you cannot do this. This is in practice what I would consider an actual trivial UaF, because straight line examples you’ve presented are so easily automatically detected and presented.I don't see how my example is a trivial straight line UaF or double free.Your entire example is predicated on code that goes:m_ptr = new{may free}{may free}{may free}delete m_ptrThis can cause UaF, but static analysis is _very_ good a dealing with lifetime->potential lifetime change->potential lifetime change->potential lifetime change->…Which is why this is generally not a control flow that causes significant concern.Where we run into problems isf(new T){do something}Delete an object{do something}Resize an object{query a cache}{map a function over an array}……Examples where the entire lifetime and use of a function is bound essentially to a single lexical scope are _vastly_ easier to reason about. That’s why rust’s lifetime model, and the borrow checking, is derived from lexical scoping. It makes reasoning about object lifetime something that can be reasoned about locally.Given the current implementation of delete,If you pass the pointer by copy, when you return back to the caller, nothing can tell if the resource was freed inside the callees.Nothing can tell you by your model either - unless you use a handle to that pointer, at which point you have either moved your lifetime issues from the pointer referenced by the handle, to the lifetime of the handle itself, _or_ you use any of the variety of RAII types available to you that make this something that _you_ can reason about.If you pass by reference, you have to zero out the pointer manually in the callee scope (error prone).But you cannot store the reference unless the “reference” is either a smart pointer (rendering the feature moot) or creating an implicit allocation of an object that holes your reference, which means you need to control that lifetime.So, for an analyzer, it cannot tell what happens inside the callees unless it traverses all the calling tree, inside each callee...., and that is not trivial!This is exactly what static analyzers already do, and are very good at it, they break down and struggle one you break the linear lifetime flow your example is using.But your suggestion of a compiler flag, would do the job I guess.That would only resolve the lvalue you delete - it can’t update every other reference.If that is something you want, std::weak_ptr provides such a functionality.—Oliver-- Std-Proposals mailing listStd-Proposals_at_[hidden]://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-08-24 20:26:00