title: Uses of memory_order_relaxed
body: <p>There are already a few questions on Stackoverflow that essentially ask about the use cases of <code>memory_order_relaxed</code>, such as:</p>
  
  <p><a href="https://stackoverflow.com/questions/31150809/understanding-memory-order-relaxed">Understanding memory_order_relaxed</a></p>
  
  <p><a href="https://stackoverflow.com/questions/23487372/what-are-some-use-cases-for-memory-order-relaxed">What are some use cases for memory_order_relaxed</a></p>
  
  <p>However, I'm still confused about the precise semantics of <code>memory_order_relaxed</code>.  Generally, the example use case for <code>memory_order_relaxed</code> is something like <code>std::shared_ptr</code> - basically it keeps an atomic counter, but it doesn't need to sync with other threads.</p>
  
  <p>Okay, so my understanding is as follows:</p>
  
  <p><code>std::memory_order_relaxed</code>, when used with <code>load()</code> only guarantees that the thread which loads it will do so atomically - it makes no guarantee about any orderings with respect to other threads that do <code>store()</code> operations on the same variable, and it makes absolutely no guarantee about any loads/stores of non-atomic variables (i.e. no memory fence will be generated.)</p>
  
  <p>But does <code>memory_order_relaxed</code> provide ANY sort of "happens-before" type ordering ability, with regard <em>only</em> to the single atomic value?  For example, if we have:</p>
  
  <pre><code>std::atomic_flag x = ATOMIC_FLAG_INIT;
  
  // Thread A:
  //
  if (!x.test_and_set(std::memory_order_relaxed)) {
     std::cout &lt;&lt; "Thread A got here first!" &lt;&lt; std::endl;
  }
  
  // Thread B:
  //
  if (!x.test_and_set(std::memory_order_relaxed)) {
     std::cout &lt;&lt; "Thread B got here first!" &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>In the above example, even though we used <code>memory_order_relaxed</code>, haven't we also provided a guaranteed way to reason about ordering here?  In other words, both Thread A and Thread B will be able to reason about which thread set the flag first.  It's just that, due to the relaxed ordering, neither thread A nor thread B will be able to assume anything about the values of any surrounding <em>non-atomic</em> shared variables, since there is no memory fence. Or am I incorrect here?</p>