This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++14 status.
weak_ptr::lock() should be atomicSection: 20.3.2.3.6 [util.smartptr.weak.obs] Status: C++14 Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2017-07-05
Priority: 0
View all other issues in [util.smartptr.weak.obs].
View all issues with C++14 status.
Discussion:
20.3.2.2 [util.smartptr.shared]/4 says: "For purposes of determining the presence of a data race, member functions shall
access and modify only the shared_ptr and weak_ptr objects themselves and not objects they refer to. Changes
in use_count() do not reflect modifications that can introduce data races." This requires shared_ptr/weak_ptr
implementations to protect their strong and weak refcounts with atomic operations, without the Standardese having to say this
elsewhere. However, 20.3.2.3.6 [util.smartptr.weak.obs]/5 describes weak_ptr::lock() with
"Returns: expired() ? shared_ptr<T>() : shared_ptr<T>(*this)."
Even after considering the blanket wording about
data races, this specification is insufficient. If this conditional expression were literally implemented, the use_count()
could change from nonzero to zero after testing expired(), causing shared_ptr<T>(*this) to throw
bad_weak_ptr when the intention is for weak_ptr::lock() to return empty or nonempty without throwing — indeed,
weak_ptr::lock() is marked as noexcept.
We all know what weak_ptr::lock() should do, the Standardese just doesn't say it.
shared_ptr(const weak_ptr<Y>&)'s specification is not really affected because
20.3.2.2.2 [util.smartptr.shared.const]/23-27 describes the behavior with English instead of code.
[Issaquah 2014-02-11: Move to Immediate]
Proposed resolution:
This wording is relative to N3691.
Edit 20.3.2.3.6 [util.smartptr.weak.obs]/5 as indicated:
shared_ptr<T> lock() const noexcept;-5- Returns:
expired() ? shared_ptr<T>() : shared_ptr<T>(*this), executed atomically.