<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2422: std::numeric_limits&lt;T&gt;::is_modulo description: "most machines" errata</title>
<meta property="og:title" content="Issue 2422: std::numeric_limits&lt;T&gt;::is_modulo description: &quot;most machines&quot; errata">
<meta property="og:description" content="C++ library issue. Status: C++17">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2422.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++17">C++17</a> status.</em></p>
<h3 id="2422"><a href="lwg-defects.html#2422">2422</a>. <code>std::numeric_limits&lt;T&gt;::is_modulo</code> description: "most machines" errata</h3>
<p><b>Section:</b> 17.3.5.2 <a href="https://wg21.link/numeric.limits.members">[numeric.limits.members]</a> <b>Status:</b> <a href="lwg-active.html#C++17">C++17</a>
 <b>Submitter:</b> Melissa Mears <b>Opened:</b> 2014-08-06 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="lwg-index.html#numeric.limits.members">issues</a> in [numeric.limits.members].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++17">C++17</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The seemingly non-normative (?) paragraph 61 (referring to N3936) describing how "most machines" define 
<code>std::numeric_limits&lt;T&gt;::is_modulo</code> in [numeric.limits.members] appears to have some issues, in my opinion.
</p>
<blockquote>
<p>
-61- On most machines, this is <code>false</code> for floating types, <code>true</code> for unsigned integers, and <code>true</code> 
for signed integers.
</p>
</blockquote>
<p>
Issues I see:
</p>
<ol>
<li><p>Very minor: change clause 2 to "this is <code>false</code> for floating <ins>point</ins> types". Other uses of the term 
say "floating point types" rather than just "floating types" &mdash; see nearby <code>is_iec559</code>, <code>tinyness_before</code>, 
etc.</p></li>
<li><p><code>is_modulo</code> <em>must</em> be <code>true</code> for unsigned integers in order to be compliant with the Standard; 
this is not just for "most machines". For reference, this requirement is from [basic.fundamental] paragraph 4 with its 
footnote 48.</p></li>
<li><p>Depending on the definition of "most machines", <code>is_modulo</code> could be <code>false</code> for most machines' signed 
integer types. GCC, Clang and Visual Studio, the 3 most popular C++ compilers by far, by default treat signed integer overflow 
as undefined.</p></li>
</ol>
<p>
As an additional note regarding the definition of <code>is_modulo</code>, it seems like it should be explicitly mentioned that 
on an implementation for which signed integer overflow is undefined, <code>is_modulo</code> shall be <code>false</code> for signed 
integer types. It took bugs filed for all three of these compilers before they finally changed (or planned to change) 
<code>is_modulo</code> to <code>false</code> for signed types.
</p>

<p><i>[2014-12 telecon]</i></p>

<p>
HH: agree with the proposal, don't like the phrasing<br/>
AM: second note feels a bit wooly<br/>
WB: not even happy with the first note, notes shouldn't say "shall"<br/>
JW: the original isn't very prescriptive because "on most machines" is not something the standard controls.<br/>
AM: "On most machines" should become a note too?<br/>
AM: first note is repeating something defined in core, shouldn't say it normatively here. Change "shall" to "is"?<br/>
MC: don't like "signed integer overflow is left undefined" ... it's just plain undefined.<br/>
AM: implementations can define what they do in that case and provide guarantees.<br/>
WB: in paragraph 61, would like to see "this" replaced by "is_modulo"<br/>
AM: Move to Open 
</p>

<p><i>[2015-05-05 Lenexa]</i></p>

<p>Marshall: I will contact the submitter to see if she can re-draft the Proposed Resolution</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<ol>
<li><p>Edit 17.3.5.2 <a href="https://wg21.link/numeric.limits.members">[numeric.limits.members]</a> around p60 as indicated:</p>

<blockquote>
<pre>
static constexpr bool is_modulo;
</pre>
<p>
-60- True if the type is modulo.(footnote) A type is modulo if, for any operation involving <code>+</code>, <code>-</code>, or <code>*</code> 
on values of that type whose result would fall outside the range <code>[min(), max()]</code>, the value returned differs from
the true value by an integer multiple of <code>max() - min() + 1</code>.
<p/>
<ins>-??- [<i>Note</i>: <code>is_modulo</code> shall be <code>true</code> for unsigned integer types (6.9.2 <a href="https://wg21.link/basic.fundamental">[basic.fundamental]</a>). &mdash; 
<i>end note</i>]</ins>
<p/>
<ins>-??- [<i>Note</i>: <code>is_modulo</code> shall be <code>false</code> for types for which overflow is undefined on the implementation, 
because such types cannot meet the modulo requirement. Often, signed integer overflow is left undefined on implementations. &mdash; 
<i>end note</i>]</ins>
<p/>
-61- On most machines, this is <code>false</code> for floating <ins>point</ins> types<del>, <code>true</code> for unsigned integers, 
and <code>true</code> for signed integers</del>.
<p/>
-62- Meaningful for all specializations.
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2016-05-21 Melissa Mears comments and provides improved wording]</i></p>

<p>
GCC and Clang have <code>-fwrapv</code> and MSVC (as of a May 2016 preview build)
has <code>/d2UndefIntOverflow-</code> as compiler command line flags to define
signed integer overflow as wrapping.  Such implementations can't set
<code>is_modulo</code> to <code>true</code> for signed integer types when these options are
enabled, because if translation units using opposite settings were
linked together, the One Definition Rule would be violated.
</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<ol>
<li><p>Edit 17.3.5.2 <a href="https://wg21.link/numeric.limits.members">[numeric.limits.members]</a> around p60 as indicated:</p>

<blockquote>
<pre>
static constexpr bool is_modulo;
</pre>
<p>
-60- True if the type is modulo.(footnote) A type is modulo if, for any operation involving <code>+</code>, <code>-</code>, 
or <code>*</code> on values of that type whose result would fall outside the range <code>[min(), max()]</code>, the value 
returned differs from the true value by an integer multiple of <code>max() - min() + 1</code>.
<p/>
<ins>-??- [<i>Note</i>: <code>is_modulo</code> is <code>true</code> for unsigned integer types (6.9.2 <a href="https://wg21.link/basic.fundamental">[basic.fundamental]</a>). &mdash; 
<i>end note</i>]</ins>
<p/>
<ins>-??- [<i>Note</i>: <code>is_modulo</code> is <code>false</code> for signed integer types (6.9.2 <a href="https://wg21.link/basic.fundamental">[basic.fundamental]</a>) 
unless an implementation, as an extension to this International Standard, defines signed integer overflow to wrap as
specified by the reference mentioned in footnote 217. &mdash; <i>end note</i>]</ins>
<p/>
<ins>-??- [<i>Note</i>: <code>is_modulo</code> is <code>false</code> for floating point types on most machines. 
&mdash; <i>end note</i>]</ins>
<p/>
<del>-61- On most machines, this is <code>false</code> for floating types, <code>true</code> for unsigned 
integers, and <code>true</code> for signed integers</del>.
<p/>
-62- Meaningful for all specializations.
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2016-06, Oulu]</i></p>

<p>
We believe that the notes about unsigned integer types and floating point types are already evident from what
the standard describes and should be removed. Furthermore the suggested note for signed integer types really shouldn't refer to a
footnote in the own document, because footnotes have no stable identifiers. The below given revised resolution
has been changed accordingly.
</p>
<p><i>[2016-06 Oulu]</i></p>

<p>Added rationalization for changes. Moved to Ready.</p>
<p>Friday: status to Immediate</p>


<p id="res-2422"><b>Proposed resolution:</b></p>
<ol>
<li><p>Edit 17.3.5.2 <a href="https://wg21.link/numeric.limits.members">[numeric.limits.members]</a> around p60 as indicated:</p>

<blockquote>
<pre>
static constexpr bool is_modulo;
</pre>
<p>
-60- True if the type is modulo.(footnote) A type is modulo if, for any operation involving <code>+</code>, <code>-</code>, 
or <code>*</code> on values of that type whose result would fall outside the range <code>[min(), max()]</code>, the value 
returned differs from the true value by an integer multiple of <code>max() - min() + 1</code>.
<p/>
<ins>-??- [<i>Example</i>: <code>is_modulo</code> is <code>false</code> for signed integer types (6.9.2 <a href="https://wg21.link/basic.fundamental">[basic.fundamental]</a>) 
unless an implementation, as an extension to this International Standard, defines signed integer overflow to wrap. &mdash; 
<i>end example</i>]</ins>
<p/>
<del>-61- On most machines, this is <code>false</code> for floating types, <code>true</code> for unsigned 
integers, and <code>true</code> for signed integers</del>.
<p/>
-62- Meaningful for all specializations.
</p>
</blockquote>
</li>
</ol>





</body>
</html>
