<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 23: Num_get overflow result</title>
<meta property="og:title" content="Issue 23: Num_get overflow result">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue23.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#CD1">CD1</a> status.</em></p>
<h3 id="23"><a href="lwg-defects.html#23">23</a>. Num_get overflow result</h3>
<p><b>Section:</b> 28.3.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Nathan Myers <b>Opened:</b> 1998-08-06 <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#facet.num.get.virtuals">active issues</a> in [facet.num.get.virtuals].</p>
<p><b>View all other</b> <a href="lwg-index.html#facet.num.get.virtuals">issues</a> in [facet.num.get.virtuals].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>The current description of numeric input does not account for the
possibility of overflow. This is an implicit result of changing the
description to rely on the definition of scanf() (which fails to
report overflow), and conflicts with the documented behavior of
traditional and current implementations. </p>

<p>Users expect, when reading a character sequence that results in a
value unrepresentable in the specified type, to have an error
reported. The standard as written does not permit this. </p>

<p><b>Further comments from Dietmar:</b></p>

<p>
I don't feel comfortable with the proposed resolution to issue 23: It
kind of simplifies the issue to much. Here is what is going on:
</p>

<p>
Currently, the behavior of numeric overflow is rather counter intuitive
and hard to trace, so I will describe it briefly:
</p>

<ul>
  <li>
    According to 28.3.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a>
    paragraph 11 <code>failbit</code> is set if <code>scanf()</code> would
    return an input error; otherwise a value is converted to the rules
    of <code>scanf</code>.
  </li>
  <li> 
    <code>scanf()</code> is defined in terms of <code>fscanf()</code>. 
  </li>
  <li>
    <code>fscanf()</code> returns an input failure if during conversion no
    character matching the conversion specification could be extracted
    before reaching EOF. This is the only reason for <code>fscanf()</code>
    to fail due to an input error and clearly does not apply to the case
    of overflow.
  </li>
  <li>
    Thus, the conversion is performed according to the rules of
    <code>fscanf()</code> which basically says that <code>strtod</code>,
    <code>strtol()</code>, etc. are to be used for the conversion.
  </li>
  <li>
    The <code>strtod()</code>, <code>strtol()</code>, etc. functions consume as
    many matching characters as there are and on overflow continue to
    consume matching characters but also return a value identical to
    the maximum (or minimum for signed types if there was a leading minus)
    value of the corresponding type and set <code>errno</code> to <code>ERANGE</code>.
  </li>
  <li>
    Thus, according to the current wording in the standard, overflows
    can be detected! All what is to be done is to check <code>errno</code>
    after reading an element and, of course, clearing <code>errno</code>
    before trying a conversion. With the current wording, it can be
    detected whether the overflow was due to a positive or negative
    number for signed types.
  </li>
</ul>

<p><b>Further discussion from Redmond:</b></p>

<p>The basic problem is that we've defined our behavior,
including our error-reporting behavior, in terms of C90.  However,
C90's method of reporting overflow in scanf is not technically an
"input error".  The <code>strto_*</code> functions are more precise.</p>

<p>There was general consensus that <code>failbit</code> should be set
upon overflow.  We considered three options based on this:</p>
<ol>
<li>Set failbit upon conversion error (including overflow), and 
    don't store any value.</li>
<li>Set failbit upon conversion error, and also set <code>errno</code> to 
    indicated the precise nature of the error.</li>
<li>Set failbit upon conversion error.  If the error was due to
    overflow, store +-numeric_limits&lt;T&gt;::max() as an
    overflow indication.</li>
</ol>

<p>Straw poll: (1) 5; (2) 0; (3) 8.</p>


<p>Discussed at Lillehammer.  General outline of what we want the
  solution to look like: we want to say that overflow is an error, and
  provide a way to distinguish overflow from other kinds of errors.
  Choose candidate field the same way scanf does, but don't describe
  the rest of the process in terms of format.  If a finite input field
  is too large (positive or negative) to be represented as a finite
  value, then set failbit and assign the nearest representable value.
  Bill will provide wording.</p>

<p>
Discussed at Toronto:
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2327.pdf">N2327</a>
is in alignment with the direction we wanted to go with in Lillehammer.  Bill
to work on.
</p>



<p id="res-23"><b>Proposed resolution:</b></p>

<p>
Change 28.3.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a>, end of p3:
</p>

<blockquote>
<p>
<b>Stage 3:</b> <del>The result of stage 2 processing can be one of</del>
<ins>The sequence of <code>char</code>s accumulated in stage 2 (the field) is
converted to a numeric value by the rules of one of the functions declared
in the header <code>&lt;cstdlib&gt;</code>:</ins>
</p>
<ul>
<li>
<del>A sequence of <code>char</code>s has been accumulated in stage 2 that is
converted (according to the rules of <code>scanf</code>) to a value of the
type of <i>val</i>. This value is stored in <i>val</i> and <code>ios_base::goodbit</code> is
stored in <i>err</i>.</del>
<ins>For a signed integer value, the function <code>strtoll</code>.</ins>
</li>
<li>
<del>The sequence of <code>char</code>s accumulated in stage 2 would have caused
<code>scanf</code> to report an input failure. <code>ios_base::failbit</code> is
assigned to <i>err</i>.</del>
<ins>For an unsigned integer value, the function <code>strtoull</code>.</ins>
</li>
<li>
<ins>For a floating-point value, the function <code>strtold</code>.</ins>
</li>
</ul>
<p>
<ins>The numeric value to be stored can be one of:</ins>
</p>
<ul>
<li><ins>zero, if the conversion function fails to convert the entire field.
<code>ios_base::failbit</code> is assigned to err.</ins></li>
<li><ins>the most positive representable value, if the field represents a value
too large positive to be represented in <i>val</i>. <code>ios_base::failbit</code> is assigned
to <i>err</i>.</ins></li>
<li><ins>the most negative representable value (zero for unsigned integer), if
the field represents a value too large negative to be represented in <i>val</i>.
<code>ios_base::failbit</code> is assigned to <i>err</i>.</ins></li>
<li><ins>the converted value, otherwise.</ins></li>
</ul>

<p><ins>
The resultant numeric value is stored in <i>val</i>.
</ins></p>
</blockquote>

<p>
Change 28.3.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a>, p6-p7:
</p>

<blockquote>
<pre>
iter_type do_get(iter_type <i>in</i>, iter_type <i>end</i>, ios_base&amp; <i>str</i>, 
                 ios_base::iostate&amp; <i>err</i>, bool&amp; <i>val</i>) const;
</pre>
<blockquote>
<p>
-6- <i>Effects:</i> If
<code>(<i>str</i>.flags()&amp;ios_base::boolalpha)==0</code> then input
proceeds as it would for a <code>long</code> except that if a value is being
stored into <i>val</i>, the value is determined according to the
following: If the value to be stored is 0 then <code>false</code> is stored.
If the value is 1 then <code>true</code> is stored. Otherwise
<del><code><i>err</i>|=ios_base::failbit</code> is performed and no value</del> <ins><code>true</code></ins> is
stored<del>.</del> <ins>and <code>ios_base::failbit</code> is assigned to <i>err</i>.</ins>
</p>
<p>
-7- Otherwise target sequences are determined "as if" by calling the
members <code>falsename()</code> and <code>truename()</code> of the facet
obtained by <code>use_facet&lt;numpunct&lt;charT&gt;
&gt;(<i>str</i>.getloc())</code>. Successive characters in the range
<code>[<i>in</i>,<i>end</i>)</code> (see 23.1.1) are obtained and matched
against corresponding positions in the target sequences only as
necessary to identify a unique match. The input iterator <i>in</i> is
compared to <i>end</i> only when necessary to obtain a character. If <del>and
only if</del> a target sequence is uniquely matched, <i>val</i> is set to the
corresponding value. <ins>Otherwise <code>false</code> is stored and <code>ios_base::failbit</code>
is assigned to <i>err</i>.</ins>
</p>
</blockquote>
</blockquote>





</body>
</html>
