shared_ptr unique()
and use_count()
Section: 20.3.2.2.6 [util.smartptr.shared.obs] Status: Resolved Submitter: Hans Boehm Opened: 2016-09-22 Last modified: 2018-06-12
Priority: 2
View all other issues in [util.smartptr.shared.obs].
View all issues with Resolved status.
Discussion:
The removal of the "debug only" restriction for use_count()
and unique()
in shared_ptr
by LWG 2434 introduced a bug. In order for unique()
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 of unique()
. 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 probably misleading.
unique()
use memory_order_acquire
, and specifying that reference count
decrement operations synchronize with unique()
. That still doesn't give us sequential consistency by default,
like we're supposed to have. But the violations seem sufficiently obscure that I think it's OK. All uses that
anybody should care about will work correctly, and the bad uses are clearly bad. I agree with Peter that this
version of unique()
may be quite useful.
I would prefer to specify use_count()
as only providing an unreliable hint of the actual count (another way
of saying debug only). Or deprecate it, as JF suggested. We can't make use_count()
reliable without adding
substantially more fencing. We really don't want someone waiting for use_count() == 2
to determine that
another thread got that far. And unfortunately, I don't think we currently say anything to make it clear that's a
mistake.
This would imply that use_count()
normally uses memory_order_relaxed
, and unique
is
neither specified nor implemented in terms of use_count()
.
[2016-10-27 Telecon]
Priority set to 2
[2018-06 Rapperswil Thursday issues processing]
This was resolved by P0521, which was adopted in Jacksonville.
Proposed resolution: