shared_ptr
deleter not specified to observe expired weak_ptr
instancesSection: 20.3.2.2.3 [util.smartptr.shared.dest] Status: New Submitter: Aaron Jacobs Opened: 2016-07-21 Last modified: 2017-10-08
Priority: 4
View all other issues in [util.smartptr.shared.dest].
View all issues with New status.
Discussion:
The C++14 standard contains no language that guarantees the deleter run by a
shared_ptr
will see all associated weak_ptr
instances as expired. For example,
the standard doesn't appear to guarantee that the assertion in the following
snippet won't fire:
std::weak_ptr<Foo> weak; std::shared_ptr<Foo> strong{ new Foo, [&weak] (Foo* f) { assert(weak.expired()); delete f; }, }; weak = strong; strong.reset();
It seems clear that the intent is that associated weak_ptr
s are expired,
because otherwise shared_ptr
deleters could resurrect a reference to an object
that is being deleted.
use_count()
caused by the destructor is sequenced before the call to the
deleter or the call to delete p
.
[2016-11-08, Jonathan and STL suggest NAD]
STL and Jonathan feel that the example has unspecified behaviour, and the assertion is allowed to fire, and that's OK (the program's expectation is not reasonable). Otherwise it's necessary to move-construct a copy of the deleter and use that copy to destroy the owned pointer. We do not want to be required to do that.
See also 2262.
[2017-09-20, Jonathan comments]
I'd like to withdraw my NAD suggestion. The value of use_count()
is already observable during the destructor via
shared_ptr
and weak_ptr
objects that share ownership, so specifying when it changes ensures correct
behaviour.
Proposed resolution: