unique_ptr
and shared_ptr
Section: 20.3.2.2.2 [util.smartptr.shared.const] Status: C++17 Submitter: Jonathan Wakely Opened: 2014-07-03 Last modified: 2017-07-30
Priority: 2
View other active issues in [util.smartptr.shared.const].
View all other issues in [util.smartptr.shared.const].
View all issues with C++17 status.
Discussion:
unique_ptr
guarantees that it will not invoke its deleter if it stores
a null pointer, which is useful for deleters that must not be called
with a null pointer e.g.
unique_ptr<FILE, int(*)(FILE*)> fptr(file, &::fclose);
However, shared_ptr
does invoke the deleter if it owns a null pointer,
which is a silent change in behaviour when transferring
ownership from unique_ptr
to shared_ptr
. That means the following
leads to undefined behaviour:
std:shared_ptr<FILE> fp = std::move(fptr);
Peter Dimov's suggested fix is to construct an empty shared_ptr
from a
unique_ptr
that contains a null pointer.
[2015-01-18 Library reflector vote]
The issue has been identified as Tentatively Ready based on eight votes in favour.
Proposed resolution:
This wording is relative to N4296.
Change 20.3.2.2.2 [util.smartptr.shared.const] p29 as indicated:
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);[…]
-29- Effects: Ifr.get() == nullptr
, equivalent toshared_ptr()
. Otherwise, ifD
is not a reference type, equivalent toshared_ptr(r.release(), r.get_deleter())
. Otherwise, equivalent toshared_ptr(r.release(), ref(r.get_deleter()))
Equivalent to.shared_ptr(r.release(), r.get_deleter())
whenD
is not a reference type, otherwiseshared_ptr(r.release(), ref(r.get_deleter()))