title: GCC warns without cast, while MSVC warns with cast, why?
body: <p>I have a C library that allows user to <code>#define</code> a integer type and generate a function specialized for that integer type, much like C++ template function.</p>
  
  <pre><code>#define THE_INTTYPE  signed short
  </code></pre>
  
  <p>The function needs to know the minimum value that can be represent by <code>THE_INTTYPE</code>. For user's convenience, I do not require them to <code>#define</code> it. Instead, I set the most significant bit to get it.</p>
  
  <pre><code>typedef THE_INTTYPE rInt;
  enum { /* assume */ char_bit = 8 };
  rInt const rMin = ((rInt)1 &lt;&lt; (sizeof(rInt) * char_bit - 1));
  </code></pre>
  
  <p>At this point, MSVC2017 at warning level 4 gives no warning, but <code>gcc -pedantic -Wall</code> gives <code>warning: overflow in implicit constant conversion [-Woverflow]</code>. I understand why it complains though. It's because I've stepped over the MSB of signed integer.</p>
  
  <blockquote>
    <p>Whoa, the integer value implicitly converted from positive (before shift) to negative (after shift)! Seems like a mistake, better warns him. - GCC thought</p>
  </blockquote>
  
  <p>I assert my intention by adding <code>(rInt)</code> cast so it becomes <code>(rInt)((rInt)1 &lt;&lt;...</code>. GCC no longer complains. MSVC2017, however, surprisingly gives a warning now: <code>warning C4310: cast truncates constant value</code>.</p>
  
  <p>At last, I managed to "fix" it by casting the <code>1</code> to <code>uintmax_t</code>.</p>
  
  <pre><code>/* Perfect no warning code */
  rInt const rMin = (rInt)((uintmax_t)1 &lt;&lt; (sizeof(rInt) * char_bit - 1));
  </code></pre>
  
  <p>The question is, why? If MSVC2017 is stricter than GCC, why does it give warning if and only if I added the cast? <strong>Why did MSVC2017 decide to give warning only after I added the cast?</strong> Did I miss anything here?</p>
  
  <pre><code>((signed short)1) -&gt; 0000 0000 0000 0001
  &lt;&lt; (2 * 8 - 1) -&gt; 1000 0000 0000 0000 // GCC warns, understandable, MSVC no warn
  (signed short)((signed short)1 ... // GCC no warn, MSVC warns, why?
  </code></pre>