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.
3237. LWG 3038 and 3190 have inconsistent PRsSection: 20.5.3.3 [mem.poly.allocator.mem] Status: C++20 Submitter: Casey Carter Opened: 2019-07-18 Last modified: 2021-02-25
Priority: 2
View all other issues in [mem.poly.allocator.mem].
View all issues with C++20 status.
Discussion:
Both LWG 3038(i) and LWG 3190(i) deal with how to respond to requests to allocate "n * sizeof(T)
" bytes of memory when n * sizeof(T)
is not sufficient storage for n
objects of type T
, i.e., when n > SIZE_MAX / sizeof(T)
. LWG 3038(i) changed polymorphic_allocator::allocate
to throw length_error
upon detecting this condition, whereas LWG 3190(i) changed allocator::allocate
to throw bad_array_new_length
. It's peculiar that two standard library components which allocate memory both detect this condition but handle it by throwing different exception types; for consistency, the two should be harmonized.
bad_array_new_length
was the better option. Unlike length_error
, bad_array_new_length
derives from bad_alloc
so we can make this change without altering the invariant that allocation functions either succeed or throw an exception derived from bad_alloc
. Further, P0339R6 "polymorphic_allocator<>
as a vocabulary type" recently added the function template "template<class T> T* allocate_object(size_t n = 1);
" to std::pmr::polymorphic_allocator
, which is another instance of the "allocate memory for n
objects of type T
" pattern. 20.5.3.3 [mem.poly.allocator.mem] paragraph 8.1 specifies that allocate_object
throws length_error
when SIZE_MAX / sizeof(T) < n
, presumably for consistency with std::pmr::polymorphic_allocator::allocate
specified in paragraph 1. allocate_object
's behavior should be consistent with allocator::allocate
and polymorphic_allocator::allocate
so we have a single means of communicating "request for allocation of unrepresentable size" errors in the Standard Library.
[2020-02 Moved to Immediate on Thursday afternoon in Prague.]
Proposed resolution:
This wording is relative to N4820.
Modify 20.5.3.3 [mem.poly.allocator.mem] as indicated:
[[nodiscard]] Tp* allocate(size_t n);[…]-1- Effects: If
SIZE_MAX / sizeof(Tp) < n
, throwslength_error bad_array_new_length
. Otherwise equivalent to:return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));template<class T> T* allocate_object(size_t n = 1);-8- Effects: Allocates memory suitable for holding an array of
n
objects of typeT
, as follows:
(8.1) — if
SIZE_MAX / sizeof(T) < n
, throwslength_error bad_array_new_length
,(8.2) — otherwise equivalent to:
return static_cast<T*>(allocate_bytes(n*sizeof(T), alignof(T)));
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4