title: Why >>24 causes -Wconversion but >>23 doesn't?
body: <p>Here is the code:</p>
  
  <pre><code>#include &lt;stdint.h&gt;
  
  unsigned char f(uint32_t RGBA)
  {
    return (RGBA&gt;&gt;24) &amp; 0xFF;
  }
  </code></pre>
  
  <p>When compiled with <code>-Wconversion</code> it causes "warning: conversion to ‘unsigned char’ from ‘uint32_t {aka unsigned int}’ may alter its value [-Wconversion]". If I lower the shift value to 23 or less the warning disappears.</p>
  
  <p>I've looked through the C99 standard and I don't understand what happens here. If I remove the <code>&amp;</code> operator then the warning is always emitted and that is probably good, as the result of the expression (after integer promotions) is larger than <code>unsigned char</code>. My only idea is that the warning is omitted for smaller shifts only because gcc is smart and sees that the result is 8-bit anyway, as the standard doesn't make this a special case. Am I right here?</p>
  
  <p>And why does the shift value matter? Is that a GCC bug? Clang seems to not produce the warning for any shift values.</p>
  
  <p>I'm using GCC 5.3.1 on a 64-bit Linux system.</p>