title: What is the exact value range for unsigned long?
body: <p>I am working through the exercises in the book "Learn C the hard way". Exercise 7 asks the reader to find the value which makes the range of an <code>unsigned long</code> exceed.</p>
  
  <blockquote>
    <p>Change <code>long</code> to <code>unsigned long</code> and try to find the number that makes it too big. </p>
  </blockquote>
  
  <p>So my approach is to first get the size of an <code>unsigned long</code> on my machine:</p>
  
  <pre><code>printf("SIZEOF ULONG: %lu", sizeof(unsigned long));
  </code></pre>
  
  <p>This prints <code>8</code> as a result. So assuming that an <code>unsigned long</code> will take up 64 bits on my machine I looked up the maximum range on <a href="https://en.wikipedia.org/wiki/Integer_(computer_science)" rel="noreferrer">Wikipedia</a>.</p>
  
  <p>64-Bits (word, doubleword, longword, long long, quad, quadword, qword, int64)</p>
  
  <ul>
  <li>Unsigned: From 0 to 18,446,744,073,709,551,615</li>
  </ul>
  
  <p>I was expecting that declaring an <code>unsigned long</code> with the above value would compile without warnings until I increment the value by 1. The result is different though. compiling the following program results in a warning.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  int main()
  {
      unsigned long value = 18446744073709551615;
      printf("SIZEOF ULONG: %lu", sizeof(unsigned long));
      printf("VALUE: %lu", value);
      return 0;
  }
  
  bla.c: In function ‘main’:
  bla.c:5:27: warning: integer constant is so large that it is unsigned
       unsigned long value = 18446744073709551615;
                             ^~~~~~~~~~~~~~~~~~~~
  </code></pre>
  
  <p>So why does gcc complain about the value being to large, I thought I already declared it as <code>unsigned</code>?</p>