This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2415. Inconsistency between `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 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.

1. 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: If `r.get() == nullptr`, equivalent to `shared_ptr()`. Otherwise, if `D` is not a reference type, equivalent to `shared_ptr(r.release(), r.get_deleter())`. Otherwise, equivalent to `shared_ptr(r.release(), ref(r.get_deleter()))`Equivalent to `shared_ptr(r.release(), r.get_deleter())` when `D` is not a reference type, otherwise `shared_ptr(r.release(), ref(r.get_deleter()))`.