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

3304. Allocate functions of std::polymorphic_allocator should require [[nodiscard]]

Section: 20.4.3 [mem.poly.allocator.class] Status: C++20 Submitter: Hiroaki Ando Opened: 2019-10-16 Last modified: 2021-02-25

Priority: 3

View all other issues in [mem.poly.allocator.class].

View all issues with C++20 status.

Discussion:

[[nodiscard]] is specified for std::polymorphic_allocator<>::allocate().

But the allocate functions added with P0339R6 doesn't have it.

Isn't [[nodiscard]] necessary for these functions?

[2019-11 Priority to 3 during Monday issue prioritization in Belfast]

[2019-11 After discussion with LEWG, assigning to LEWG]

[2019-11-4; Daniel comments]

This issue is related to LWG 3312.

[2019-11; Friday AM in Belfast. Status changed to "Ready"]

Proposed resolution:

This wording is relative to N4835.

  1. Modify 20.4.3 [mem.poly.allocator.class], class template polymorphic_allocator synopsis, as indicated:

    namespace std::pmr {
      template<class Tp = byte> class polymorphic_allocator {
        […]
        // 20.4.3.3 [mem.poly.allocator.mem], member functions
        [[nodiscard]] Tp* allocate(size_t n);
        void deallocate(Tp* p, size_t n);
    
        [[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
        void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
        template<class T> [[nodiscard]] T* allocate_object(size_t n = 1);
        template<class T> void deallocate_object(T* p, size_t n = 1);
        template<class T, class... CtorArgs> [[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
        template<class T> void delete_object(T* p);  
        […]
      };  
    }
    
  2. Modify 20.4.3.3 [mem.poly.allocator.mem] as indicated:

    [[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
    

    -5- Effects: Equivalent to: return memory_rsrc->allocate(nbytes, alignment);

    […]

    […]
    template<class T>
      [[nodiscard]] T* allocate_object(size_t n = 1);
    

    -8- Effects: Allocates memory suitable for holding an array of n objects of type T, as follows:

    1. (8.1) — if SIZE_MAX / sizeof(T) < n, throws length_error,

    2. (8.2) — otherwise equivalent to:

      return static_cast<T*>(allocate_bytes(n*sizeof(T), alignof(T)));
      

    […]

    template<class T, class CtorArgs...>
      [[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
    

    -11- Effects: Allocates and constructs an object of type T, as follows. Equivalent to:

    T* p = allocate_object<T>();
    try {
      construct(p, std::forward<CtorArgs>(ctor_args)...);
    } catch (...) {
      deallocate_object(p);
      throw;
    }
    return p;
    

    […]