From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id B924A3858D39; Fri, 3 Nov 2023 08:06:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B924A3858D39 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1698998798; bh=qL6W83fv+N9m5+GqSqGasX4GKi3zq2kqUxjvLzWcT+I=; h=From:To:Subject:Date:In-Reply-To:References:From; b=nGYBGIv0MjUiH1eEspfoKWSlkB8/V3nmCR/cwD9F8ebSeoYhtGoG9vgm/Jdriu+tG EBxrv9cKKTJtYUlM83aGBMjn9SIqWXUwwxEMF75ScdiPv1sPnKQlEkjBglO8rnvAPH jie27854MoOdwRfZLgbA0nbkM/xPS5qUY0P/JLnI= From: "federico at kircheis dot it" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/112335] missed optimization on reset and assign unique_ptr Date: Fri, 03 Nov 2023 08:06:37 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 14.0 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: normal X-Bugzilla-Who: federico at kircheis dot it X-Bugzilla-Status: RESOLVED X-Bugzilla-Resolution: INVALID X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D112335 --- Comment #7 from Federico Kircheis --- Thank you Jonathan, I've then misunderstood the example of Andrew, I though= t he was trying to create a scenario where after reset the pointer is not nullpt= r. > Demo: https://godbolt.org/z/PWd96j4fz Thank you for the example, but honestly, I think I am still missing somethi= ng. If you modify the main this way ---- int main() { global =3D nullptr; std::unique_ptr local1(new s); bar1(global, local1); global =3D nullptr; std::unique_ptr local2(new s); bar1(global, local2); } ---- or this way ---- int main() { global =3D nullptr; std::unique_ptr local1(new s); bar2(global, local1); global =3D nullptr; std::unique_ptr 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 delet= er *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 using s =3D int; // for simplicity void bar1(std::unique_ptr& ps1, std::unique_ptr& ps2){ ps1.reset(); ps1 =3D std::move(ps2); } void bar2(std::unique_ptr& ps1, std::unique_ptr& ps2){ ps1 =3D std::move(ps2); } void bar3(std::unique_ptr& ps1, std::unique_ptr& ps2){ ps1.reset(); ps1.reset(); ps1 =3D std::move(ps2); } ---- While you are right that bar1 and bar2 have different behavior if they poin= t 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.=