title: Compiler optimizations and temporary assignments in C and C++
body: <p>Please see the following code valid in C and C++:</p>
  
  <pre><code>extern int output;
  extern int input;
  extern int error_flag;
  
  void func(void)
  {
    if (0 != error_flag)
    {
      output = -1;
    }
    else
    {
      output = input;
    }
  }
  </code></pre>
  
  <ol>
  <li><p>Is the compiler allowed to compile the above code in the same way as if it looked like below?</p>
  
  <pre><code>extern int output;
  extern int input;
  extern int error_flag;
  
  void func(void)
  {
    output = -1;
    if (0 == error_flag)
    {
      output = input;
    }
  }
  </code></pre>
  
  <p>In other words, is the compiler allowed to generate (from the first snippet) code that always makes a temporary assignment of -1 to <code>output</code> and then assign <code>input</code> value to <code>output</code> depending on <code>error_flag</code> status?</p></li>
  <li><p>Would the compiler be allowed to do it if <code>output</code> would be declared as volatile?</p></li>
  <li><p>Would the compiler be allowed to do it if <code>output</code> would be declared as <code>atomic_int</code> (stdatomic.h)?</p></li>
  </ol>
  
  <p>Update after David Schwartz's comment:</p>
  
  <p>If the compiler is free to add additional writes to a variable, it seems it is not possible to tell from the C code whether a data race exists or not. How to determine this?</p>