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.
shared_ptr
deleters must not not throw on move constructionSection: 20.3.2.2.2 [util.smartptr.shared.const] Status: C++17 Submitter: Jonathan Wakely Opened: 2016-05-03 Last modified: 2017-07-30
Priority: 0
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:
In 20.3.2.2.2 [util.smartptr.shared.const] p8 the shared_ptr
constructors taking
a deleter say:
The copy constructor and destructor of
D
shall not throw exceptions.
It's been pointed out that this doesn't forbid throwing moves, which makes it difficult to avoid a leak here:
struct D { D() = default; D(const D&) noexcept = default; D(D&&) { throw 1; } void operator()(int* p) const { delete p; } }; shared_ptr<int> p{new int, D{}};
"The copy constructor" should be changed to reflect that the chosen constructor might not be a copy constructor, and that copies made using any constructor must not throw.
N.B. the same wording is used for the allocator argument, but that's
redundant because the Allocator
requirements already forbid exceptions
when copying or moving.
Proposed resolution:
[Drafting note: the relevant expressions we're concerned about are
enumerated in the CopyConstructible
and MoveConstructible
requirements, so I see no need to repeat them by saying something
clunky like "Initialization of an object of type D
from an expression
of type (possibly const) D
shall not throw exceptions", we can just
refer to them. An alternative would be to define
NothrowCopyConstructible
, which includes CopyConstructible
but
requires that construction and destruction do not throw.]
Change 20.3.2.2.2 [util.smartptr.shared.const] p8:
D
shall beCopyConstructible
and such construction shall not throw exceptions. Thecopy constructor anddestructor ofD
shall not throw exceptions.