title: Does standard C++11 guarantee that `volatile atomic<T>` has both semantics (volatile + atomic)?
body: <p>As known, <code>std::atomic</code> and <code>volatile</code> are different things.</p>
  
  <p>There are 2 main differences:</p>
  
  <ol>
  <li><p>Two optimizations can be for <code>std::atomic&lt;int&gt; a;</code>, but can't be for <code>volatile int a;</code>:</p>
  
  <ul>
  <li>fused operations: <code>a = 1; a = 2;</code> can be replaced by the compiler on <code>a = 2;</code></li>
  <li>constant propagation: <code>a = 1; local = a;</code> can be replaced by the compiler on<code>a = 1; local = 1;</code></li>
  </ul></li>
  <li><p>Reordering of ordinary reads/writes across atomic/volatile operations:</p>
  
  <ul>
  <li>for <code>volatile int a;</code> any volatile-read/write-operations can't be reordered. But nearby ordinary reads/writes can still be reordered around volatile reads/writes.</li>
  <li>for <code>std::atomic a;</code> reordering of nearby ordinary reads/writes restricted based on the memory barrier used for atomic operation <code>a.load(std::memory_order_...);</code></li>
  </ul></li>
  </ol>
  
  <p>I.e. <code>volatile</code> don't introduce a memory fences, but <code>std::atomic</code> can do it. </p>
  
  <p>As is well described in the article:</p>
  
  <ul>
  <li>Herb Sutter, January 08, 2009 - part 1: <a href="http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484" rel="noreferrer">http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484</a></li>
  <li>Herb Sutter, January 08, 2009 - part 2: <a href="http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484?pgno=2" rel="noreferrer">http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484?pgno=2</a></li>
  </ul>
  
  <p>For example, <code>std::atomic</code> should be used for concurrent multi-thread programs (CPU-Core &lt;-> CPU-Core), but <code>volatile</code> should be used for access to Mamory Mapped Regions on devices (CPU-Core &lt;-> Device).</p>
  
  <hr>
  
  <p>But if required, both have unusual semantics and has any or all of the atomicity and/or ordering guarantees needed for lock-free coding, i.e. if required <code>volatile std::atomic&lt;&gt;</code>, require for several reasons:</p>
  
  <ul>
  <li><strong>ordering</strong>: to prevent reordering of ordinary reads/writes, for example, for reads from CPU-RAM, to which the data been written using the Device DMA-controller</li>
  </ul>
  
  <p>For example:</p>
  
  <pre><code>char cpu_ram_data_written_by_device[1024];
  device_dma_will_write_here( cpu_ram_data_written_by_device );
  
  // physically mapped to device register
  volatile bool *device_ready = get_pointer_device_ready_flag();
  
  //... somewhere much later
  while(!device_ready); // spin-lock (here should be memory fence!!!)
  for(auto &amp;i : cpu_ram_data_written_by_device) std::cout &lt;&lt; i;
  </code></pre>
  
  <ul>
  <li><strong>spilling</strong>: CPU write to CPU-RAM and then Device DMA-controller read from this memory: <a href="https://en.wikipedia.org/wiki/Register_allocation#Spilling" rel="noreferrer">https://en.wikipedia.org/wiki/Register_allocation#Spilling</a></li>
  </ul>
  
  <p>example:</p>
  
  <pre><code>char cpu_ram_data_will_read_by_device[1024];
  device_dma_will_read_it( cpu_ram_data_written_by_device );
  
  // physically mapped to device register
  volatile bool *data_ready = get_pointer_data_ready_flag();
  
  //... somewhere much later
  for(auto &amp;i : cpu_ram_data_will_read_by_device) i = 10;
  data_ready=true; //spilling cpu_ram_data_will_read_by_device to RAM, should be memory fence
  </code></pre>
  
  <ul>
  <li><strong>atomic</strong>: to guarantee that the volatile operation will be atomic - i.e. It will consist of a single operation instead of multiple - i.e. one 8-byte-operation instead of two 4-byte-operations</li>
  </ul>
  
  <p>For this, Herb Sutter said about <code>volatile atomic&lt;T&gt;</code>, January 08, 2009: <a href="http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484?pgno=2" rel="noreferrer">http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484?pgno=2</a></p>
  
  <blockquote>
    <p>Finally, to express a variable that both has unusual semantics and has
    any or all of the atomicity and/or ordering guarantees needed for
    lock-free coding, only the ISO C++0x draft Standard provides a direct
    way to spell it: volatile atomic.</p>
  </blockquote>
  
  <p>But do <strong>modern</strong> standards C++11 (not C++0x draft), C++14, and C++17 guarantee that <code>volatile atomic&lt;T&gt;</code> has both semantics (volatile + atomic)?</p>
  
  <p>Does <code>volatile atomic&lt;T&gt;</code> guarantee the most stringent guarantees from both volatile and atomic?</p>
  
  <ol>
  <li>As in <code>volatile</code>: Avoids fused-operations and constant-propagation as described in the beginning of the question</li>
  <li>As in <code>std::atomic</code>: Introduces memory fences to provide ordering, spilling, and being atomic.</li>
  </ol>
  
  <p>And can we do <code>reinterpret_cast</code> from <code>volatile int *ptr;</code> to <code>volatile std::atomic&lt;int&gt;*</code>?</p>