2179. enable_shared_from_this and construction from raw pointers

Section: 23.11.6 [util.smartptr.enab], 23.11.3.1 [util.smartptr.shared.const] Status: Resolved Submitter: Daniel Krügler Opened: 2012-08-16 Last modified: 2017-09-10

Priority: 3

View all other issues in [util.smartptr.enab].

View all issues with Resolved status.

Discussion:

On reflector message c++std-lib-32927, Matt Austern asked whether the following example should be well-defined or not

struct X : public enable_shared_from_this<X> { };
auto xraw = new X;
shared_ptr<X> xp1(xraw);
shared_ptr<X> xp2(xraw);

pointing out that 23.11.3.1 [util.smartptr.shared.const] does not seem to allow it, since xp1 and xp2 aren't allowed to share ownership, because each of them is required to have use_count() == 1. Despite this wording it might be reasonable (and technical possible) to implement that request.

On the other hand, there is the non-normative note in 23.11.6 [util.smartptr.enab] p11 (already part of TR1):

The shared_ptr constructors that create unique pointers can detect the presence of an enable_shared_from_this base and assign the newly created shared_ptr to its __weak_this member.

Now according to the specification in 23.11.3.1 [util.smartptr.shared.const] p3-7:

template<class Y> explicit shared_ptr(Y* p);

the notion of creating unique pointers can be read to be included by this note, because the post-condition of this constructor is unique() == true. Evidence for this interpretation seems to be weak, though.

Howard Hinnant presented the counter argument, that actually the following is an "anti-idiom" and it seems questionable to teach it to be well-defined in any case:

auto xraw = new X;
shared_ptr<X> xp1(xraw);
shared_ptr<X> xp2(xraw);

He also pointed out that the current post-conditions of the affected shared_ptr constructor would need to be reworded.

It needs to be decided, which direction to follow. If this idiom seems too much broken to be supported, the note could be improved. If it should be supported, the constructors in 23.11.3.1 [util.smartptr.shared.const] need a careful analysis to ensure that post-conditions are correct.

Several library implementations currently do not support this example, instead they typically cause a crash. Matt points out that there are currently no explicit requirements imposed on shared_ptr objects to prevent them from owning the same underlying object without sharing the ownership. It might be useful to add such a requirement.

[2013-03-15 Issues Teleconference]

Moved to Open.

More discussion is needed to pick a direction to guide a proposed resolution.

[2013-05-09 Jonathan comments]

The note says the newly created shared_ptr is assigned to the weak_ptr member. It doesn't say before doing that the shared_ptr should check if the weak_ptr is non-empty and possibly share ownership with some other pre-existing shared_ptr.

[2015-08-26 Daniel comments]

LWG issue 2529 is independent but related to this issue.

[2016-03-16, Alisdair comments]

This issues should be closed as Resolved by paper p0033r1 at Jacksonville.

Proposed resolution: