Date: Sat, 23 Aug 2025 17:36:27 +0100
Really?void somefn() { auto ptr = std::make_unique(5); auto ptr2 = std::unique_ptr<int>(ptr.get()); // Maybe this shouldhave been .release() ?}In this example you did two things:1- you are breaking the smart pointer contract intentionally (that's not how we use them)2- you are jumping back and forth between two worlds, smart pointers and raw pointersMy proposal is meant to catch unintentional wrong usage.If you break an API contract you have to be careful since there is no safe guards.If you scan through the standard library, you will find some function that deals with raw pointers directly std::destroy_at, std::construct_at, std::deallocate.....etc All these take pointers by copy, so if you fall in the following case:{ m_ptr = std::allocate(...); //..... std::deallocate(m_ptr);//.... after some lines std::deallocate(m_ptr);}Because the pointer is passed by copy, nothing will tell if the resource is still alive.Double-free using smart pointers. Sure, I had to work at it (or usedthe wrong member function), but it's possible.That's impossible, because the smart pointers purpose is to prevent it, if used as by its usage contract.> > I didn't say that the originating pointer is deleted/freed, I said its> > lifetime ends. The pointer, not what it's pointing at.> >> > ... example with arbitrary class receiving a pointer to a dynamically allocated object ...> >> > ... example how this breaks even std::unique_ptr ...> You are mixing between raw pointers usage and smart pointers usage.No, I'm implementing a smart pointer which breaks almost immediatelyupon construction, and breaks further if one attempts to move it, oreven dereference it. Assuming the guideline is being used.Once more, smart pointers have their usage, and this proposal addresses problems outside that realm.> Passing by copy, creates resources ownership confusion.> Passing the pointer variable by reference imposes on it to outlive all the references, but at the same time, if any of these variables is a parameter to the delete operator, then it's guaranteed to become nullptr as per the proposal, so no false ownership.> that's the guideline purpose.Which breaks things. You don't get to hand-wave away the carnagethat the guideline imposes. ("Why can't I drive through red lights?""Because there exists cross-traffic". "Yeah, ignore that.")> Let's forget the passing by reference thing....just focus on the delete operator which nullify it's pointer parameter. I don't see why it is not the standard..So throw away the part of the proposal that (if it didn't break thingsalong the way) was supposed to address the truly useful part (alsoassuming that dereferencing nullptr were defined behaviour)? OK:Undefined behavior as per the standard , but segfault consensus by CPU's and microchips....Almost all processing units of any size, consider the address 0 and its vicinity as special memory addresses.If we're focusing on just having the delete operator able to set itsargument to nullptr: it doesn't address the plethora of other copiesof the pointer still pointing at now released memory, Setting its argument to nullptr alone has local effect only on the pointer itself, but adding the guideline 'passing the pointer by reference instead of copy to callee' will add convention to how it will live and die.The 'reference' concept, means that the referenced object ensures that it will outlive all its references.Expl{ // std::vector v{1,2 3} : defined outside auto val = v[1]; foo_clears_vec(v); val = ...; // dangling ref}Operator[ ] returns a reference, but does not guarantee that the referenced value outlives its reference.That's why I'm against returning by reference from containers. Because you don't control lifetime of what you get from the container. { T someval; takeByRef(someval);}But if you pass a reference to a user, you have the control to keep the referenced outlives its references.Passing by reference is almost like a signal-slot implementation, for free.and those arethe cases that are harder for the compiler and other static analyzersto detect. I'm not seeing the value in imposing a dead write (inwell-defined C++ programs) on every delete call. The folk who aredoing the "low level code" (and who can tolerate the use of dynamicmemory in some form) are also the folk who are quite sensitive toextra operations.Slowly slowly resolving one problem a time.
Received on 2025-08-23 16:36:38