title: How can shift left << give different results in different functions?
body: <p>I have been debugging a problem in a C++ library, and found a strange difference between <strong>literal 0</strong> and a <strong>variable set to 0</strong> but <strong>only inside the library</strong>. If I copy the code out into my own code it works as expected.</p>
  
  <p>The library code is shifting a <code>1</code> down a long integer to mask off one bit at a time. When sending a certain code (REPEAT key) you send a kind of dummy data packet, and "no bits" so it transmits the headers and no data. I was assuming the for-loop would skip the loop if there were no bits to send.</p>
  
  <p>I have simplified it down to break apart the assignment, and added the following debugging. I'm just repeating the steps for both <code>nbits</code> and the literal <code>0</code> I added.</p>
  
  <pre><code>void  IRsend::sendNEC (unsigned long data,  int nbits){
  
      Serial.println(data, HEX);
      Serial.print(" nbits = ");
      Serial.println( nbits);
      if(nbits == 0) Serial.println("nbits == 0"); else Serial.println("nbits != 0 "); 
      Serial.print(" 0 - 1 = ");
      Serial.println(0 - 1);
      Serial.print(" nbits - 1 = ");
      Serial.println(nbits - 1);
      Serial.print(" (1UL &lt;&lt; (0 - 1) = ");
      Serial.println(1UL &lt;&lt; (0 - 1));
      Serial.print(" (1UL &lt;&lt; (nbits - 1) = ");
      Serial.println(1UL &lt;&lt; (nbits - 1));
      ...
  
      // the part I was originally debugging:
          for (unsigned long  mask = 1UL &lt;&lt; (nbits - 1);  mask;  mask &gt;&gt;= 1) {
      ...
  }
  
  called like:
  
    irsend.sendNEC(0xFFFFFFFF, 0);
  
  </code></pre>
  
  <p>This surprisingly gives the following output:</p>
  
  <pre><code>FFFFFFFF
   nbits = 0
   nbits == 0
   0 - 1 = -1
   nbits - 1 = -1
   (1UL &lt;&lt; (0 - 1) = 0
   (1UL &lt;&lt; (nbits - 1) = 1
  </code></pre>
  
  <p>How can the last two results be different? <code>nbit</code> is 0, so why does literal 0 shift differently when they both end up as -1 (I added the extra parentheses to be sure)?</p>
  
  <p>And why, when I copy the exact same debug code into my code which calls that library, and call a test function like: </p>
  
  <pre><code>void runtest(unsigned long data,  int nbits){
  /// same debug ... 
  }
  void setup() {
    runtest(0xFFFFFFFF, 0);
  }
  
  </code></pre>
  
  <p>I get the expected output:</p>
  
  <pre><code>-- Same test again --
  FFFFFFFF
   nbits = 0
  nbits == 0
   0 - 1 = -1
   nbits - 1 = -1
   (1UL &lt;&lt; (0 - 1) = 0
   (1UL &lt;&lt; (nbits - 1) = 0
  </code></pre>
  
  <p>I can only guess that 0 == 0 exactly, e.g. if its defaulting to a longer type 0?</p>
  
  <p>This is using the Arduino IRRemote library: <a href="https://github.com/z3t0/Arduino-IRremote/blob/master/ir_NEC.cpp" rel="nofollow noreferrer">https://github.com/z3t0/Arduino-IRremote/blob/master/ir_NEC.cpp</a> </p>
  
  <p>Its running on an ATmega328, I'm building on MacOSX presumably with avr-gcc in the Arduino 1.8.10 IDE.</p>