https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112335
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED --- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Federico Kircheis from comment #5) > I do not think that the case you have in mind is supported by the standard, It is. The standard is very clear about exactly which operations happen, and in which order. Code can rely on that behaviour, because it's guaranteed by the standard. Implementations are not allowed to deviate from that. In your 'bar1' function when the ~s destructor runs it is guaranteed that it will observe ps1.get() == nullptr, because that's the first thing that ps1.reset() does. In your 'bar2' function when the ~s destructor runs it's guaranteed that it will observe ps1.get() == the original value of ps2, because that value gets set before invoking the deleter. Demo: https://godbolt.org/z/PWd96j4fz That is clearly an observable difference, which is required by the standard, and so your bar1 and bar2 are clearly not equivalent. But a much simpler example where the difference is observable is when the two arguments to bar1 and bar2 are the same object: https://godbolt.org/z/z8fsTan8K For bar1 you destroy any pointed-to object, then move-assign an empty pointer to itself, which does nothing. So bar1(p, p,) is equivalent to p.reset(); For bar2 you release the pointer, then reset it back again. So bar2(p, p) is a no-op. The functions are not clearly equivalent. > but the postcondition does not hold with some deleters, so not sure if that > could be relevant here I'm not sure what you mean here. The postcondition holds unless the deleter *also* destroys the unique_ptr itself.