<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2162: allocator_traits::max_size missing noexcept</title>
<meta property="og:title" content="Issue 2162: allocator_traits::max_size missing noexcept">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2162.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++14">C++14</a> status.</em></p>
<h3 id="2162"><a href="lwg-defects.html#2162">2162</a>. <code>allocator_traits::max_size</code> missing <code>noexcept</code></h3>
<p><b>Section:</b> 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a>, 20.2.9.3 <a href="https://wg21.link/allocator.traits.members">[allocator.traits.members]</a>, 20.2.9 <a href="https://wg21.link/allocator.traits">[allocator.traits]</a> <b>Status:</b> <a href="lwg-active.html#C++14">C++14</a>
 <b>Submitter:</b> Bo Persson <b>Opened:</b> 2012-07-03 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#allocator.requirements">active issues</a> in [allocator.requirements].</p>
<p><b>View all other</b> <a href="lwg-index.html#allocator.requirements">issues</a> in [allocator.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++14">C++14</a> status.</p>
<p><b>Discussion:</b></p>

<p>
N3376 describes in 20.2.9.3 <a href="https://wg21.link/allocator.traits.members">[allocator.traits.members]</a>/7
</p>
<blockquote><pre>
static size_type max_size(Alloc&amp; a);
</pre>
<p>
<i>Returns</i>: <code>a.max_size()</code> if that expression is well-formed; otherwise, <code>numeric_limits&lt;size_type&gt;::max()</code>.
</p>
</blockquote>
<p>
The <code>max_size</code> function is supposed to call one of two functions that are both <code>noexcept</code>. 
To make this intermediate function useful for containers, it should preserve the <code>noexcept</code> attribute.
<p/>
Proposed changes:
<p/>
In 20.2.9 <a href="https://wg21.link/allocator.traits">[allocator.traits]</a> and 20.2.9.3 <a href="https://wg21.link/allocator.traits.members">[allocator.traits.members]</a>/7, change the function signature to
</p>
<blockquote><pre>
static size_type max_size(Alloc&amp; a) noexcept;
</pre></blockquote>

<p><i>[2012-08-05 Daniel comments]</i></p>

<p>
On the first sight this does not seem like a defect of the specification, because the Allocator requirements in 
16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a> (Table 28) do not impose a no-throw requirement onto <code>max_size()</code>; 
the table just describes the fall-back implementation for <code>max_size()</code> if a given allocator does 
not provide such a function.
<p/>
<code>std::allocator</code> as a special model of this concept and is allowed to increase the exception-guarantees 
for <code>max_size()</code>, but this does not imply a corresponding rules for other allocators.
<p/>
Furthermore, <code>max_size()</code> of Containers is <em>not</em> specified in terms of 
<code>Allocator::max_size()</code>, so again this is not a real contradiction.
<p/>
Nonetheless I think that the following stronger decision should be considered:
</p>
<ol>
<li><p>
Require that for all Allocators (as specified in 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a>) <code>max_size()</code> 
never throws an exception. This would it make much more useful to call this function in situations where no 
exception should leave the context.
</p></li>
<li><p>
Require that for all Allocators (as specified in 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a>) <code>max_size()</code>
can be called on const allocator object. Together with the previous item this would allow an implementation 
of a container's <code>max_size()</code> function to delegate to the allocator's <code>max_size()</code> function.
</p></li>
</ol>
<p>
In regard to the second statement it should be mentioned that there are two current specification
deviations from that in the draft:
</p>
<ol>
<li><p>
The synopsis of 20.2.9 <a href="https://wg21.link/allocator.traits">[allocator.traits]</a> uses a const allocator argument as part of the signature
of the <code>max_size</code> function.
</p></li>

<li><p>
Both the synopsis of 20.6.1 <a href="https://wg21.link/allocator.adaptor.syn">[allocator.adaptor.syn]</a> and the member specification in
20.6.4 <a href="https://wg21.link/allocator.adaptor.members">[allocator.adaptor.members]</a> p8 declare <code>scoped_allocator_adaptor::max_size</code>
as const member function, but this function delegates to 
</p>
<blockquote><pre>
allocator_traits&lt;OuterAlloc&gt;::max_size(outer_allocator())
</pre></blockquote>
<p>
where <code>outer_allocator()</code> resolves to the member function overload returning a
<code>const outer_allocator_type&amp;</code>.
</p>
</li>
</ol>

<p>
The question arises whether these current defects actually point to a defect in the Allocator
requirements and should be fixed there.
</p>

<p><i>[
2012-10 Portland: Move to Review 
]</i></p>


<p>
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.
</p>

<p>
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 <code>throw</code>
expressions into disguised <code>terminate</code> 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.
</p>

<p>
Another option would be to make exception spefication a conditional no-except, much like we do for
some <code>swap</code> functions and assignment operators.  However, this goes against the intent of the
Madrid adoption of <code>noexcept</code> 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.
</p>

<p>
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.
</p>

<p><i>[2013-04-18, Bristol]</i></p>




<p id="res-2162"><b>Proposed resolution:</b></p>
<p>
In 20.2.9 <a href="https://wg21.link/allocator.traits">[allocator.traits]</a> and 20.2.9.3 <a href="https://wg21.link/allocator.traits.members">[allocator.traits.members]</a>/7, change the function signature to
</p>
<blockquote><pre>
static size_type max_size(Alloc&amp; a) <ins>noexcept</ins>;
</pre></blockquote>





</body>
</html>
