title: Can branches with undefined behavior be assumed unreachable and optimized as dead code?
body: <p>Consider the following statement:</p>
  
  <pre><code>*((char*)NULL) = 0; //undefined behavior
  </code></pre>
  
  <p>It clearly invokes undefined behavior. Does the existence of such a statement in a given program mean that the whole program is undefined or that behavior only becomes undefined once control flow hits this statement?</p>
  
  <p>Would the following program be well-defined in case the user never enters the number <code>3</code>?</p>
  
  <pre><code>while (true) {
   int num = ReadNumberFromConsole();
   if (num == 3)
    *((char*)NULL) = 0; //undefined behavior
  }
  </code></pre>
  
  <p>Or is it entirely undefined behavior no matter what the user enters?</p>
  
  <p>Also, can the compiler assume that undefined behavior will never be executed at runtime? That would allow for reasoning backwards in time:</p>
  
  <pre><code>int num = ReadNumberFromConsole();
  
  if (num == 3) {
   PrintToConsole(num);
   *((char*)NULL) = 0; //undefined behavior
  }
  </code></pre>
  
  <p>Here, the compiler could reason that in case <code>num == 3</code> we will always invoke undefined behavior. Therefore, this case must be impossible and the number does not need to be printed. The entire <code>if</code> statement could be optimized out. Is this kind of backwards reasoning allowed according to the standard?</p>