3005. Destruction order of arrays by make_shared/allocate_shared only recommended?

Section: 23.11.3.6 [util.smartptr.shared.create] Status: Tentatively Ready Submitter: Richard Smith Opened: 2017-08-01 Last modified: 2017-11-02

Priority: 0

View other active issues in [util.smartptr.shared.create].

View all other issues in [util.smartptr.shared.create].

View all issues with Tentatively Ready status.

Discussion:

In [util.smartptr.shared.create]/7.9 we find this:

"When the lifetime of the object managed by the return value ends, or when the initialization of an array element throws an exception, the initialized elements should be destroyed in the reverse order of their construction."

Why is this only a "should be" and not a "shall be" (or, following usual conventions for how we write requirements on the implementation, "are")? Is there some problem that means we can't require an implementation to destroy in reverse construction order in all cases?

Previous resolution: [SUPERSEDED]

This resolution is relative to N4687.

  1. Edit 23.11.3.6 [util.smartptr.shared.create] as indicated:

    template<class T, ...>
    shared_ptr<T> make_shared(args);
    template<class T, class A, ...>
    shared_ptr<T> allocate_shared(const A& a, args);
    

    […]

    -7- Remarks:

    1. […]

    2. (7.9) — When the lifetime of the object managed by the return value ends, or when the initialization of an array element throws an exception, the initialized elements areshould be destroyed in decreasing index orderthe reverse order of their construction.

[2017-11-01, Alisdair comments and suggests wording improvement]

I dislike the change of how we specify the order of destruction, which is clear (but non-normative) from the preceding paragraph making the order of construction explicit. We are replacing that with a different specification, so now I need to match up ""decreasing index order" to "ascending order of address" to infer the behavior that is worded more directly today.

P0 to change "should be" to "are" though.

Previous resolution: [SUPERSEDED]

This resolution is relative to N4700.

  1. Edit 23.11.3.6 [util.smartptr.shared.create] as indicated:

    template<class T, ...>
    shared_ptr<T> make_shared(args);
    template<class T, class A, ...>
    shared_ptr<T> allocate_shared(const A& a, args);
    

    […]

    -7- Remarks:

    1. […]

    2. (7.9) — When the lifetime of the object managed by the return value ends, or when the initialization of an array element throws an exception, the initialized elements areshould be destroyed in the reverse order of their construction.

[2017-11-01]

The rationale for the "decreasing index order" change in the original P/R suggested by Richard Smith had been presented as that user code may destroy one or more array elements and construct new ones in their place. In those cases shared_ptr has no way of knowing the construction order, so it cannot ensure that the destruction order reverses it.
Richard: Perhaps something like:

the initialized elements are should be destroyed in the reverse order of their original construction.

would work?

[ 2017-11-02 Moved to Tentatively Ready after 10 positive votes for P0 on c++std-lib. ]

Proposed resolution:

This resolution is relative to N4700.

  1. Edit 23.11.3.6 [util.smartptr.shared.create] as indicated:

    template<class T, ...>
    shared_ptr<T> make_shared(args);
    template<class T, class A, ...>
    shared_ptr<T> allocate_shared(const A& a, args);
    

    […]

    -7- Remarks:

    1. […]

    2. (7.9) — When the lifetime of the object managed by the return value ends, or when the initialization of an array element throws an exception, the initialized elements areshould be destroyed in the reverse order of their original construction.