From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id F0B203858D38; Thu, 2 Nov 2023 17:23:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F0B203858D38 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1698945811; bh=69E9e8edGBpzqGay8vSbeFM6zVKDrkZq1nDORgJ0jOU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Qg4OEA12xIfRq9oLNbepiamDUgh3btxeY+eiIxSKAgo+F/1bL2yDN4ptzi1ssLe08 s6eal1tTME/61Nulyk8TJj9Xn5I1WN7yCerpQT3WB0GjcQB3FGTUiRh5vw2M8Dh9Uf j5X2Tx0id2RGLLYp9UotdqquiqzFpPKQ80ME+pgQ= From: "redi at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/112335] missed optimization on reset and assign unique_ptr Date: Thu, 02 Nov 2023 17:23:31 +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: redi at gcc dot gnu.org 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: resolution bug_status 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 Jonathan Wakely changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED --- Comment #6 from Jonathan Wakely --- (In reply to Federico Kircheis from comment #5) > I do not think that the case you have in mind is supported by the standar= d, It is. The standard is very clear about exactly which operations happen, an= d 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() =3D=3D 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() =3D=3D 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 t= wo 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 point= er 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) i= s a no-op. The functions are not clearly equivalent. > but the postcondition does not hold with some deleters, so not sure if th= at > could be relevant here I'm not sure what you mean here. The postcondition holds unless the deleter *also* destroys the unique_ptr itself.=