title: Is the max value of size_t (SIZE_MAX) defined relative to the other integer types?
body: <p>I'm writing a library of functions that will safely convert between various numeric types or die trying.
  My intent is roughly equal parts create-useful-library and learn-C-edge-cases.</p>
  
  <p>My <code>int</code>-to-<code>size_t</code> function is triggering a GCC <code>-Wtype-limits</code> warning that claims I shouldn't test if an <code>int</code> is greater than <code>SIZE_MAX</code>, because it will never be true.
  (Another function that converts <code>int</code> to <code>ssize_t</code> produces an identical warning about <code>SSIZE_MAX</code>.)</p>
  
  <p>My MCVE, with extra comments and baby steps, is:</p>
  
  <pre><code>#include &lt;stdint.h&gt;  /* SIZE_MAX */
  #include &lt;stdlib.h&gt;  /* exit EXIT_FAILURE size_t */
  
  extern size_t i2st(int value) {
      if (value &lt; 0) {
          exit(EXIT_FAILURE);
      }
      // Safe to cast --- not too small.
      unsigned int const u_value = (unsigned int) value;
      if (u_value &gt; SIZE_MAX) {  /* Line 10 */
          exit(EXIT_FAILURE);
      }
      // Safe to cast --- not too big.
      return (size_t) u_value;
  }
  </code></pre>
  
  <h2>The Compiler Warnings</h2>
  
  <p>I'm getting similar warnings from GCC 4.4.5 on Linux 2.6.34:</p>
  
  <pre class="lang-none prettyprint-override"><code>$ gcc -std=c99 -pedantic -Wall -Wextra -c -o math_utils.o math_utils.c
  
  math_utils.c: In function ‘i2st’:
  math_utils.c:10: warning: comparison is always false due to limited range of data type
  </code></pre>
  
  <p>...and also from GCC 4.8.5 on Linux 3.10.0:</p>
  
  <pre class="lang-none prettyprint-override"><code>math_utils.c: In function ‘i2st’:
  math_utils.c:10:5: warning: comparison is always false due to limited range of data type [-Wtype-limits]
       if (u_value &gt; SIZE_MAX) {  /* Line 10 */
       ^
  </code></pre>
  
  <p>These warnings don't appear justified to me, at least not in the general case.
  (I don't deny that the comparison might be
  "always false"
  on some particular combination of hardware and compiler.)</p>
  
  <h2>The C Standard</h2>
  
  <p>The C 1999 standard does not appear to rule out an <code>int</code> being greater than <code>SIZE_MAX</code>.</p>
  
  <p>Section
  "6.5.3.4 The <code>sizeof</code> operator"
  doesn't address <code>size_t</code> at all, except to describe it as
  "defined in <code>&lt;stddef.h&gt;</code> (and other headers)".</p>
  
  <p>Section
  "7.17 Common definitions <code>&lt;stddef.h&gt;</code>"
  defines <code>size_t</code> as
  "the unsigned integer type of the result of the <code>sizeof</code> operator".
  (Thanks, guys!)</p>
  
  <p>Section
  "7.18.3 Limits of other integer types"
  is more helpful ---
  it defines
  "limit of <code>size_t</code>" as:</p>
  
  <blockquote>
    <p><code>SIZE_MAX</code>        <code>65535</code></p>
  </blockquote>
  
  <p>...meaning <code>SIZE_MAX</code> could be as <em>small</em> as 65535.
  An <code>int</code>
  (signed or unsigned)
  could be much greater than that, depending on the hardware and compiler.</p>
  
  <h2>Stack Overflow</h2>
  
  <p>The accepted answer to
  "<a href="https://stackoverflow.com/questions/131803"><code>unsigned int</code> vs. <code>size_t</code></a>"
  seems to support my interpretation
  (emphasis added):</p>
  
  <blockquote>
    <p>The <code>size_t</code> type may be bigger than, equal to, <strong>or smaller than</strong> an <code>unsigned int</code>, and your compiler might make assumptions about it for optimization.</p>
  </blockquote>
  
  <p>This answer cites the same
  "Section 7.17"
  of the C standard that I've already quoted.</p>
  
  <h2>Other Documents</h2>
  
  <p>My searches turned up the Open Group's paper
  "<a href="http://www.unix.org/whitepapers/64bit.html" rel="noreferrer">Data Size Neutrality and 64-bit Support</a>",
  which claims under
  "64-bit Data Models"
  (emphasis added):</p>
  
  <blockquote>
    <p>ISO/IEC 9899:1990, Programming Languages - C (ISO C)
    left the definition of the <code>short int</code>, the <code>int</code>, the <code>long int</code>, and the <code>pointer</code> deliberately vague
    [...]
    The only constraints were that <code>int</code>s must be no smaller than <code>short</code>s, and <code>long</code>s must be no smaller than <code>int</code>s, and <strong><code>size_t</code> must represent the largest unsigned type supported by an implementation</strong>.
    [...]
    The relationship between the fundamental data types can be expressed as:</p>
    
    <blockquote>
      <p><code>sizeof(char)</code> &lt;= <code>sizeof(short)</code> &lt;= <code>sizeof(int)</code> &lt;= <strong><code>sizeof(long)</code> = <code>sizeof(size_t)</code></strong></p>
    </blockquote>
  </blockquote>
  
  <p>If this is true, then testing an <code>int</code> against <code>SIZE_MAX</code> is indeed futile...
  but this paper doesn't cite chapter-and-verse, so I can't tell how its authors reached their conclusion.
  Their own
  "Base Specification Version 7"
  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html" rel="noreferrer"><code>sys/types.h</code> docs</a>
  don't address this either way.</p>
  
  <h2>My Question</h2>
  
  <p>I understand that <code>size_t</code> is unlikely to be narrower than an <code>int</code>, but <strong>does the C standard guarantee</strong> that comparing <code>some_unsigned_int &gt; SIZE_MAX</code> will <em>always</em> be false?
  If so, where?</p>
  
  <h2>Not-Duplicates</h2>
  
  <p>There are two semi-duplicates of this question, but they are both asking more general questions about what <code>size_t</code> is supposed to represent and when it should / should-not be used.</p>
  
  <ul>
  <li><p>"<a href="https://stackoverflow.com/questions/2550774">What is <code>size_t</code> in C?</a>"
  does not address the relationship between <code>size_t</code> and the other integer types.
  Its accepted answer is just a quote from Wikipedia, which doesn't provide any information beyond what I've already found.</p></li>
  <li><p>"<a href="https://stackoverflow.com/questions/32286535">What is the correct definition of <code>size_t</code>?</a>"
  starts off nearly a duplicate of my question, but then veers off course, asking
  when <code>size_t</code> should be used and why it was introduced.
  It was closed as a duplicate of the previous question.</p></li>
  </ul>