title: Does C++20 well-define left shift for signed integers that "overflow"?
body: <p>In the current C++ Standard Draft, the left shift operator is defined as follows <a href="http://eel.is/c++draft/expr.shift#2" rel="nofollow noreferrer">[expr.shift]</a>:</p>
  
  <blockquote>
    <p>The value of <code>E1 &lt;&lt; E2</code> is <strong>the unique value</strong> congruent to <code>E1×2^E2</code> modulo <code>2^N</code>, where <code>N</code> is the width of the type of the result. </p>
  </blockquote>
  
  <p>Consider <code>int E1 = 2^31-1 = 2'147'483'647</code>, <code>E2 = 1</code>, and <code>int</code> having 32 bits. Then there is <em>an infinite number of numbers congruent to</em> <code>E1×2^E2 = 4'294'967'294</code> modulo <code>2^N = 2^32</code>, namely, all the numbers <code>4'294'967'294 + k×2^32</code> where <code>k</code> is an arbitrary integer. Examples are <code>4'294'967'294</code> (<code>k=0</code>) or <code>-2</code> (<code>k=-1</code>).</p>
  
  <p>I don't understand what the Standard means by <strong>the unique value</strong> out of these numbers. Does it mean <em>the unique value that can be represented by the resulting data type</em>? Then, I suppose the result is defined as <code>-2</code>. Is this interpretation correct?</p>
  
  <p>Until C++20, the definition was different and this case would cause undefined behavior. I suppose the change is related to the mandatory 2's-complement representation of negative signed integers.</p>
  
  <p>In fact, there is now no more requirement for <code>E1</code> to be non-negative. It therefore seems that <code>-1 &lt;&lt; 1</code> is defined as <code>-2</code>. Is that right as well?</p>