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.

Reply via email to