Title
std::(ranges::)destroy_at should destroy array elements in the decreasing index order
Status
new
Section
[specialized.destroy]
Submitter
Jiang An

Created on 2023-02-17.00:00:00 last changed 12 months ago

Messages

Date: 2023-03-22.22:40:39

Proposed resolution:

This wording is relative to N4928.

  1. Modify [version.syn], header <version> synopsis, as indicated and replace the placeholder YYYYMML by the year and month of adoption of this issue:

    […]
    #define __cpp_lib_coroutine         201902L  // also in <coroutine>
    #define __cpp_lib_destroy_at        YYYYMML  // also in <memory>
    #define __cpp_lib_destroying_delete 201806L  // also in <new>
    […]
    
  2. Modify [specialized.destroy] as indicated:

    template<class T>
      constexpr void destroy_at(T* location);
    
    namespace ranges {
      template<destructible T>
        constexpr void destroy_at(T* location) noexcept;
    }
    

    -1- Effects:

    1. (1.1) — If T is an array type, equivalent to destroy(rbeginbegin(*location), rendend(*location)).

    2. (1.2) — Otherwise, equivalent to location->~T().

Date: 2023-03-15.00:00:00

[ 2023-03-22; Reflector poll ]

Set priority to 3 after reflector poll.

Date: 2023-02-15.00:00:00

[ 2023-02-26; Daniel comments and provides alternative wording ]

The suggested fix indeed corrects an inconsistency, but also implies a silent behaviour change at runtime, since at least MSVC STL and libstdc++ implement the array destruction order as specified (others not tested). The below wording therefore suggests to introduce a specific feature macro for this, so that user code can potentially react on this, regardless of potential vendor API breakage hesitations. The natural feature macro to increase would be that which introduced the specific array destruction behavior of destroy_at, which was P0896R4, and which introduced __cpp_lib_ranges, on the other hand the specification change affects both the std::ranges and the std forms of destroy_at, so it seems plausible to suggest a new, specific feature macro for both destroy_at function templates. This is what the proposed wording does.

LWG should clarify whether an entry to [diff.cpp20] should be added as well.

Date: 2023-02-26.11:31:28

Currently, std::(ranges::)destroy_at is specified to destroy array elements in the increasing index order ([specialized.destroy]/1.1), which is inconsistent with the decreasing order specified in the core language ([class.dtor]/13) and the order for arrays created by std::make_shared and std::allocate_shared (mandated by LWG 3005).

This wording is relative to N4928.

  1. Modify [specialized.destroy] as indicated:

    template<class T>
      constexpr void destroy_at(T* location);
    
    namespace ranges {
      template<destructible T>
        constexpr void destroy_at(T* location) noexcept;
    }
    

    -1- Effects:

    1. (1.1) — If T is an array type, equivalent to destroy(rbeginbegin(*location), rendend(*location)).

    2. (1.2) — Otherwise, equivalent to location->~T().

History
Date User Action Args
2023-03-22 22:40:39adminsetmessages: + msg13476
2023-02-26 11:31:28adminsetmessages: + msg13436
2023-02-19 16:10:50adminsetmessages: + msg13424
2023-02-17 00:00:00admincreate