title: Can atomics suffer spurious stores?
body: <p>In C++, can atomics suffer spurious stores?</p>
  
  <p>For example, suppose that <code>m</code> and <code>n</code> are atomics and that <code>m = 5</code> initially. In thread 1,</p>
  
  <pre><code>    m += 2;
  </code></pre>
  
  <p>In thread 2,</p>
  
  <pre><code>    n = m;
  </code></pre>
  
  <p>Result: the final value of <code>n</code> should be either 5 or 7, right? But could it spuriously be 6? Could it spuriously be 4 or 8, or even something else?</p>
  
  <p>In other words, does the C++ memory model forbid thread 1 from behaving as though it did this?</p>
  
  <pre><code>    ++m;
      ++m;
  </code></pre>
  
  <p>Or, more weirdly, as though it did this?</p>
  
  <pre><code>    tmp  = m;
      m    = 4;
      tmp += 2;
      m    = tmp;
  </code></pre>
  
  <p>Reference: <a href="http://www.hpl.hp.com/techreports/2008/HPL-2008-56.pdf" rel="noreferrer">H.-J. Boehm &amp; S. V. Adve, 2008,</a> Figure 1. (If you follow the link, then, in the paper's section 1, see the first bulleted item: "The informal specifications provided by ...")</p>
  
  <p><strong>THE QUESTION IN ALTERNATE FORM</strong></p>
  
  <p>One answer (appreciated) shows that the question above can be misunderstood. If helpful, then here is the question in alternate form.</p>
  
  <p>Suppose that the programmer tried to tell thread 1 <em>to skip</em> the operation:</p>
  
  <pre><code>    bool a = false;
      if (a) m += 2;
  </code></pre>
  
  <p>Does the C++ memory model forbid thread 1 from behaving, at run time, as though it did this?</p>
  
  <pre><code>    m += 2; // speculatively alter m
      m -= 2; // oops, should not have altered! reverse the alteration
  </code></pre>
  
  <p>I ask because Boehm and Adve, earlier linked, seem to explain that a multithreaded execution can</p>
  
  <ul>
  <li>speculatively alter a variable, but then</li>
  <li>later change the variable back to its original value when the speculative alteration turns out to have been unnecessary.</li>
  </ul>
  
  <p><strong>COMPILABLE SAMPLE CODE</strong></p>
  
  <p>Here is some code you can actually compile, if you wish.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;atomic&gt;
  #include &lt;thread&gt;
  
  // For the orignial question, do_alter = true.
  // For the question in alternate form, do_alter = false.
  constexpr bool do_alter = true;
  
  void f1(std::atomic_int *const p, const bool do_alter_)
  {
      if (do_alter_) p-&gt;fetch_add(2, std::memory_order_relaxed);
  }
  
  void f2(const std::atomic_int *const p, std::atomic_int *const q)
  {
      q-&gt;store(
          p-&gt;load(std::memory_order_relaxed),
          std::memory_order_relaxed
      );
  }
  
  int main()
  {
      std::atomic_int m(5);
      std::atomic_int n(0);
      std::thread t1(f1, &amp;m, do_alter);
      std::thread t2(f2, &amp;m, &amp;n);
      t2.join();
      t1.join();
      std::cout &lt;&lt; n &lt;&lt; "\n";
      return 0;
  }
  </code></pre>
  
  <p>This code always prints <code>5</code> or <code>7</code> when I run it. (In fact, as far as I can tell, it always prints <code>7</code> when I run it.) However, I see nothing <em>in the semantics</em> that would prevent it from printing <code>6</code>, <code>4</code> or <code>8</code>.</p>
  
  <p>The excellent Cppreference.com <a href="http://en.cppreference.com/w/cpp/atomic" rel="noreferrer">states,</a> "Atomic objects are free of data races," which is nice, but in such a context as this, what does it mean?</p>
  
  <p>Undoubtedly, all this means that I do not understand the semantics very well. Any illumination you can shed on the question would be appreciated.</p>
  
  <p><strong>ANSWERS</strong></p>
  
  <p>@Christophe, @ZalmanStern and @BenVoigt each illuminate the question with skill. Their answers cooperate rather than compete. In my opinion, readers should heed all three answers: @Christophe first; @ZalmanStern second; and @BenVoigt last to sum up.</p>