This paper proposes a resolution to C++17 CD comment CA 14, which identified
issues with use_count
and unique
in shared_ptr
.
1. CA 14
The removal of the "debug only" restriction foruse_count
andunique
inshared_ptr
introduced a bug: in order forunique
to produce a useful and reliable value, it needs a synchronize clause to ensure that prior accesses through another reference are visible to the successful caller ofunique
. Many current implementations use a relaxed load, and do not provide this guarantee, since it’s not stated in the Standard. For debug/hint usage that was OK. Without it the specification is unclear and misleading.
2. Proposed Wording
The proposed changes are relative to [N4604], the Committee Draft for C++17.
The � character is used to denote a placeholder number which the editor shall determine.
2.1. Part A
Change 20.11.2.2.5 [util.smartptr.shared.obs] as depicted:
long use_count() const noexcept;
-7- Returns: The number ofshared_ptr
objects,*this
included, that share ownership with*this
, or 0 when*this
is empty. -�- Synchronization: None.-�- [ Note:
get() == nullptr
does not imply a specific return value ofuse_count()
. — end note ]-�- [ Note:
weak_ptr<T>::lock()
can affect the return value ofuse_count()
. — end note ]-�- [ Note: When multiple threads can affect the return value of
use_count()
, the result should be treated as approximate. In particular,use_count() == 1
does not imply that accesses through a previously destroyedshared_ptr
have in any sense completed. — end note ]
bool unique() const noexcept;
-8- Returns:use_count() == 1
.-9- [ Note: If you are usingunique()
to implement copy on write, do not rely on a specific value whenget() == nullptr
. — end note ]
2.2. Part B
Change 20.11.2.2 [util.smartptr.shared]/1 as depicted:
namespace std { template<class T> class shared_ptr { public: [...] long use_count() const noexcept;bool unique() const noexcept;; explicit operator bool() const noexcept; [...] }; [...] } // namespace std
Change 20.11.2.2.5 [util.smartptr.shared.obs] as depicted:
bool unique() const noexcept;
-8- Returns: use_count() == 1
.
Add a new section:
D.� Deprecatedshared_ptr
observers [depr.util.smartptr.shared.obs]The following member is defined in addition to those specified in [util.smartptr.shared]:
namespace std { template<class T> class shared_ptr { public: bool unique() const noexcept; }; }
bool unique() const noexcept;
Returns: use_count() == 1
.