allocator_traits::max_size
missing noexcept
Section: 16.4.4.6 [allocator.requirements], 20.2.9.3 [allocator.traits.members], 20.2.9 [allocator.traits] Status: C++14 Submitter: Bo Persson Opened: 2012-07-03 Last modified: 2016-01-28
Priority: Not Prioritized
View other active issues in [allocator.requirements].
View all other issues in [allocator.requirements].
View all issues with C++14 status.
Discussion:
N3376 describes in 20.2.9.3 [allocator.traits.members]/7
static size_type max_size(Alloc& a);Returns:
a.max_size()
if that expression is well-formed; otherwise,numeric_limits<size_type>::max()
.
The max_size
function is supposed to call one of two functions that are both noexcept
.
To make this intermediate function useful for containers, it should preserve the noexcept
attribute.
static size_type max_size(Alloc& a) noexcept;
[2012-08-05 Daniel comments]
On the first sight this does not seem like a defect of the specification, because the Allocator requirements in
16.4.4.6 [allocator.requirements] (Table 28) do not impose a no-throw requirement onto max_size()
;
the table just describes the fall-back implementation for max_size()
if a given allocator does
not provide such a function.
std::allocator
as a special model of this concept and is allowed to increase the exception-guarantees
for max_size()
, but this does not imply a corresponding rules for other allocators.
Furthermore, max_size()
of Containers is not specified in terms of
Allocator::max_size()
, so again this is not a real contradiction.
Nonetheless I think that the following stronger decision should be considered:
Require that for all Allocators (as specified in 16.4.4.6 [allocator.requirements]) max_size()
never throws an exception. This would it make much more useful to call this function in situations where no
exception should leave the context.
Require that for all Allocators (as specified in 16.4.4.6 [allocator.requirements]) max_size()
can be called on const allocator object. Together with the previous item this would allow an implementation
of a container's max_size()
function to delegate to the allocator's max_size()
function.
In regard to the second statement it should be mentioned that there are two current specification deviations from that in the draft:
The synopsis of 20.2.9 [allocator.traits] uses a const allocator argument as part of the signature
of the max_size
function.
Both the synopsis of 20.5.1 [allocator.adaptor.syn] and the member specification in
20.5.4 [allocator.adaptor.members] p8 declare scoped_allocator_adaptor::max_size
as const member function, but this function delegates to
allocator_traits<OuterAlloc>::max_size(outer_allocator())
where outer_allocator()
resolves to the member function overload returning a
const outer_allocator_type&
.
The question arises whether these current defects actually point to a defect in the Allocator requirements and should be fixed there.
[ 2012-10 Portland: Move to Review ]
Consensus that the change seems reasonable, and that for any given type the template is intantiated with the contract should be 'wide' so this meets the guidelines we agreed in Madrid for C++11.
Some mild concern that while we don't imagine many allocator implementations throwing on this method,
it is technically permited by current code that we would not be breaking, by turning throw
expressions into disguised terminate
calls. In this case, an example might be an
instrumented 'logging' allocator that writes every function call to a log file or database, and might
throw if that connection/file were no longer available.
Another option would be to make exception spefication a conditional no-except, much like we do for
some swap
functions and assignment operators. However, this goes against the intent of the
Madrid adoption of noexcept
which is that vendors are free to add such extensions, but we
look for a clear line in the library specification, and do not want to introduce conditional-noexcept
piecemeal. A change in our conventions here would require a paper addressing the library specification
as a whole.
Consensus was to move forward, but move the issue only to Review rather than Ready to allow time for further comments. This issue should be considered 'Ready' next time it is reviewed unless we get such comments in the meantime.
[2013-04-18, Bristol]
Proposed resolution:
In 20.2.9 [allocator.traits] and 20.2.9.3 [allocator.traits.members]/7, change the function signature to
static size_type max_size(Alloc& a) noexcept;