https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112335
--- Comment #9 from Federico Kircheis <federico at kircheis dot it> --- Great, thank you for the clarifications, your redacted example makes now sense. > https://godbolt.org/z/WGPTesEb3 shows that bar3 is not the same as bar1, > because it runs an additional destructor if operator delete() plays silly > games. And this is what I meant before that such program is not supported by the standard ---- void bar3(std::unique_ptr<s>& ps1, std::unique_ptr<s>& ps2){ ps1.reset(); ps1.reset(); ps1 = std::move(ps2); } --- is equivalent to ---- void bar3(std::unique_ptr<s>& ps1, std::unique_ptr<s>& ps2){ ps1.reset(); assert(ps1 == nullptr); ps1.reset(); assert(ps1 == nullptr); ps1 = std::move(ps2); } ---- which is not. And the same holds if "if (!global) global.reset(new s);" is moved into "~s()", and removed from "operator delete". If the users changes delete in such a way, at this point we have UB, as the postcondition of unique_ptr::reset does not hold (the example given by Andrew) Yes, the second ps1.reset(); is trivial to remove.