Date: Sat, 30 Aug 2025 23:08:31 +0100
> On Aug 27, 2025, at 9:41 PM, organicoman via Std-Proposals <std-proposals_at_[hidden]> wrote:> > In the example above, we have a double free bug despite the correct code.> It is not correct code. With or without the ‘throw’ you’ll have a double free. The destructor of A always gets called at some point. You are violating basic class invariance principles of RAII. And again: a unique_ptr would have solved this problem without any overhead.Nope, std::unique_ptr won't solve this problem.You must know that the delete expression can throw if the destructor of the object throws, thus, you will be UB.Plus, before RAII we should observe the "easy to use hard to misuse " principle for designing API's....delete as many other memory related functions like , std::free, std::deallocate, or kfree (kernell free)..are easy to misuse, unsafe to use(otherwise we won't have the famous memory safety issues)....if inside the call the function throws there's no way to reason about the resource (freed no freed?).That's why , taking the pointer by reference and null it asap, is the best strategy for safety.> > Anyway, I'm past this proposal now. If it is difficult to be understood, it will be difficult to be advocated for, thus not worth the effort.Actually, your proposal is quite easy to understand: You want to automatically null a pointer when it gets deleted. It is just impossible to implement without breaking any (reasonable) existing C++ code (unless recompiled). I'm not talking about the implementation (of course it is easy to understand) , I'm talking about the benefits. If all the functions above take the pointer by reference and nulls it out directly after freeing the resource, we will have the chance to:1- inspect it, either in the natural return from that function or when we return because of an exception.2- get a safe behavior, by default, if we double call the function on the same pointer3- changing the provenance of the pointer by reassigning it, doesn't cause a memory leak.4- we can optimize some pointer comparisons like for example:{ T* p = new T; Foo(p); // takes by reference and may free T* q = new T; if( p == q) // this can be optimized out { }}In the snippet above, q == p is always false, even if Foo calls delete on p then its old value gets recycled then assigned into q in the next allocation. Given (q == p) is always false, then the if statement can be optimized out.5- by setting the pointer to nullptr, it is always a good indicator for a possible change in pointer provenance, which can be used for pointer zap, or pointer provenance optimization techniques.And so many other things related to compiler analysis and optimization that I don't know off.And again: A compiler flag would work just as well. And the compiler flag wouldn’t even break any code. But, compiler flags don’t belong into the standard.I agree totally that at first it must be a compiler flags until it gets adopted by users, then maybe it will be standardized after.
Received on 2025-08-30 22:10:39