https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112335

--- Comment #7 from Federico Kircheis <federico at kircheis dot it> ---
Thank you Jonathan, I've then misunderstood the example of Andrew, I thought he
was trying to create a scenario where after reset the pointer is not nullptr.

> Demo: https://godbolt.org/z/PWd96j4fz

Thank you for the example, but honestly, I think I am still missing something.

If you modify the main this way

----
int main()
{
    global = nullptr;
    std::unique_ptr<s> local1(new s);
    bar1(global, local1);
    global = nullptr;
    std::unique_ptr<s> local2(new s);
    bar1(global, local2);
}
----


or this way


----
int main()
{
    global = nullptr;
    std::unique_ptr<s> local1(new s);
    bar2(global, local1);
    global = nullptr;
    std::unique_ptr<s> local2(new s);
    bar2(global, local2);
}
----

the output is the same.
First time it prints 0, the second time a non-0 address.

> 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

And this is absolutely correct, did not think of it.

> I'm not sure what you mean here. The postcondition holds unless the deleter 
> *also* destroys the unique_ptr itself.

As written, I was not sure if this plays a role; this is what the standard says
(and I#ve misunderstood the example of Andrew).
A similar effect can be observed in the following example

----
#include <memory>

using s = int; // for simplicity

void bar1(std::unique_ptr<s>& ps1, std::unique_ptr<s>& ps2){
    ps1.reset();
    ps1 = std::move(ps2);
}
void bar2(std::unique_ptr<s>& ps1, std::unique_ptr<s>& ps2){
    ps1 = std::move(ps2);
}

void bar3(std::unique_ptr<s>& ps1, std::unique_ptr<s>& ps2){
    ps1.reset();
    ps1.reset();
    ps1 = std::move(ps2);
}
----

While you are right that bar1 and bar2 have different behavior if they point to
the same object, bar1 and bar3 are fundamentally the same function, even in
case of aliasing.
Unless the post-condition of reset is not hold; otherwise the second
"ps1.reset()" could be completely removed, as ps1 is nullptr.

Reply via email to