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

### 2466. `allocator_traits::max_size()` default behavior is incorrect

Section: 16.4.4.6 [allocator.requirements], 20.2.9.3 [allocator.traits.members] Status: C++17 Submitter: Howard Hinnant Opened: 2015-01-17 Last modified: 2017-07-30

Priority: 3

View other active issues in [allocator.requirements].

View all other issues in [allocator.requirements].

View all issues with C++17 status.

Discussion:

Table 28 — "Allocator requirements" says that default behavior for `a.max_size()` is `numeric_limits<size_type>::max()`. And this is consistent with the matching statement for `allocator_traits` in 20.2.9.3 [allocator.traits.members]/p7:

>     static size_type max_size(const Alloc& a) noexcept;

> > Returns: `a.max_size()` if that expression is well-formed; otherwise, `numeric_limits<size_type>::max()`.

However, when allocating memory, an allocator must allocate `n*sizeof(value_type)` bytes, for example:

>     value_type*
>     allocate(std::size_t n)
>     {
>       return static_cast<value_type*>(::operator new (n * sizeof(value_type)));
>     }

When `n == numeric_limits<size_type>::max(), n * sizeof(value_type)` is guaranteed to overflow except when `sizeof(value_type) == 1`.

A more useful default would be `numeric_limits<size_type>::max() / sizeof(value_type)`.

[2015-05, Lenexa]

Marshall: Is this the right solution?
PJP: I think it's gilding the lily.
STL: I think this is right, and it doesn't interact with the incomplete container stuff because it's in a member function.
Marshall: Objections to this?
STL: Spaces around binary operators.
Hwrd: It's completely wrong without spaces.
Marshall: All in favor of Ready?
Lots.

Proposed resolution:

This wording is relative to N4296.

1. Change 16.4.4.6 [allocator.requirements], Table 28 — "Allocator requirements", as indicated:

   > Table 28 — Allocator requirements
   > Expression | Return type | Assertion/note pre-/post-condition | Default
   > --- | --- | --- | ---
   > `…`
   > `a.max_size()` | `X::size_type` | the largest value that can meaningfully be passed to `X::allocate()` | `numeric_limits<size_type>::max()/sizeof(value_type)`
   > `…`

2. Change 20.2.9.3 [allocator.traits.members]/p7 as indicated:

   >     static size_type max_size(const Alloc& a) noexcept;

   > > Returns: `a.max_size()` if that expression is well-formed; otherwise, `numeric_limits<size_type>::max()/sizeof(value_type)`.