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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Federico Kircheis from comment #5)
> I do not think that the case you have in mind is supported by the standard,

It is. The standard is very clear about exactly which operations happen, and 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() == 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() == 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 two
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 pointer
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) is a
no-op.

The functions are not clearly equivalent.

> but the postcondition does not hold with some deleters, so not sure if that
> could be relevant here

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

Reply via email to