title: Why does (infinite) recursion give different results with and w/o -O3 in clang (and gcc/g++)?
body: <p>When I compile and run this code</p>
  <pre><code>#include &lt;stdio.h&gt;
  
  int collatz(int a) {
      return a == 1 ? 1 : collatz((a%2) ? 3*a+1 : a/2);
  }
  
  int main() {
      for (int a = 0; a &lt; 10; ++a)
          printf(&quot;%d: %d\n&quot;, a, collatz(a));
  }
  </code></pre>
  <p>in <code>clang</code> (10.0.0-4ubuntu1) it crashes, but when I add <code>-O3</code> it runs fine. (This holds both when passing this as C or C++ code to <code>clang</code>.)</p>
  <p>I understand that it crashes without the optimization flag, since the call of <code>collatz</code> with <code>0</code> will lead to an infinite recursion. However, with <code>-O3</code> it returns <code>0: 1</code>, which is wrong. Is that a (known) bug in the optimization or am I missing something?</p>
  <p>(<code>gcc</code>/<code>g++</code> (9.3.0) also crash without optimization, and the compilation hangs with <code>-O3</code>.)</p>
  <p><em>Edit</em>: Just to add that I am not looking for the reason why the program hangs / fails (that is clear) but why the compiler apparently has the liberty to return some value whilst the program should not return (but enter an infinite loop).</p>
  <p><em>Edit 2</em>: Why haven't I picked a more minimal example? Well, here it is, this gives the same behavior</p>
  <pre><code>int divide(int i) {
    return i == 1 ? 1 : divide(i/2);
  } 
  </code></pre>