<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 416: definitions of XXX_MIN and XXX_MAX macros in climits</title>
<meta property="og:title" content="Issue 416: definitions of XXX_MIN and XXX_MAX macros in climits">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue416.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="416"><a href="lwg-defects.html#416">416</a>. definitions of XXX_MIN and XXX_MAX macros in climits</h3>
<p><b>Section:</b> 17.3.6 <a href="https://wg21.link/climits.syn">[climits.syn]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Martin Sebor <b>Opened:</b> 2003-09-18 <b>Last modified:</b> 2017-06-15</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
        <p>

Given two overloads of the function foo(), one taking an argument of type
int and the other taking a long, which one will the call foo(LONG_MAX)
resolve to? The expected answer should be foo(long), but whether that
is true depends on the #defintion of the LONG_MAX macro, specifically
its type. This issue is about the fact that the type of these macros
is not actually required to be the same as the the type each respective
limit.
<br/>

Section 18.2.2 of the C++ Standard does not specify the exact types of
the XXX_MIN and XXX_MAX macros #defined in the &lt;climits> and &lt;limits.h>
headers such as INT_MAX and LONG_MAX and instead defers to the C standard.
<br/>

Section 5.2.4.2.1, p1 of the C standard specifies that "The values [of
these constants] shall be replaced by constant expressions suitable for use
in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX,
the following shall be replaced by expressions that have the same type as
would an expression that is an object of the corresponding type converted
according to the integer promotions."
<br/>

The "corresponding type converted according to the integer promotions" for
LONG_MAX is, according to 6.4.4.1, p5 of the C standard, the type of long
converted to the first of the following set of types that can represent it:
int, long int, long long int. So on an implementation where (sizeof(long)
== sizeof(int)) this type is actually int, while on an implementation where
(sizeof(long) > sizeof(int)) holds this type will be long.
<br/>

This is not an issue in C since the type of the macro cannot be detected
by any conforming C program, but it presents a portability problem in C++
where the actual type is easily detectable by overload resolution.

        </p>
<p><i>[Kona: the LWG does not believe this is a defect.  The C macro
  definitions are what they are; we've got a better
  mechanism, <code>std::numeric_limits</code>, that is specified more
  precisely than the C limit macros.  At most we should add a
  nonnormative note recommending that users who care about the exact
  types of limit quantities should use &lt;limits&gt; instead of
  &lt;climits&gt;.]</i></p>


    

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

<p>
Change  [c.limits], paragraph 2:
</p>

<blockquote><p>
-2- The contents are the same as the Standard C library header <code>&lt;limits.h&gt;</code>.
<ins>[<i>Note:</i> The types of the macros in <code>&lt;climits&gt;</code> are not guaranteed
to match the type to which they refer.<i>--end note</i>]</ins>
</p></blockquote>





</body>
</html>
