title: GCC atomic builtins and volatile
body: <p>I use some global structures in a multithreaded program, some of the members are modified by multiple threads simultaneously, some others are not.</p>
  
  <p>I didn't define any of this members volatile, but anytime i use this members for both reading and writing purposes, i use atomic builtins such as __sync_fetch_and_add.</p>
  
  <p>The question is, should i define this members or the whole struct volatile?</p>
  
  <p>I think the compiler has to access the memory instead any register because of this builtins (lock prefix), should i be worried about other members that are not cause race conditions.</p>
  
  <p>I checked out the assembly output of my compiler (gcc 4.6.2) and it seems my assumption is right.</p>
  
  <p>Here is the test code.</p>
  
  <pre><code>int sum = 0;
  
  for (i=0; i&lt;2000000000; i++) {
      sum += i;
  }
  </code></pre>
  
  <p>The assembly output (-O2 -S -masm=intel)</p>
  
  <pre><code>L2:
      add edx, eax
      inc eax
      cmp eax, 2000000000
      jne L2
  </code></pre>
  
  <p>So compiler is never accessed the memory (eax = i, edx = sum)</p>
  
  <p>Here is the second test code.</p>
  
  <pre><code>volatile int sum = 0;
  
  for (i=0; i&lt;2000000000; i++) {
      sum += i;
  }
  </code></pre>
  
  <p>The assembly output</p>
  
  <pre><code>L2:
      mov edx, DWORD PTR [esp+28]
      add edx, eax
      mov DWORD PTR [esp+28], edx
      inc eax
      cmp eax, 2000000000
      jne L2
  </code></pre>
  
  <p>Compiler accessed the memory for sum everytime as expected.</p>
  
  <p>The final code, my way.</p>
  
  <pre><code>int sum = 0;
  
  for (i=0; i&lt;2000000000; i++) {
      __sync_fetch_and_add(&amp;sum , i);
  }
  </code></pre>
  
  <p>The assembly output.</p>
  
  <pre><code>L2:
      lock add    DWORD PTR [esp+28], eax
      inc eax
      cmp eax, 2000000000
      jne L2
  </code></pre>
  
  <p>Not even a temp register as before (edx), compiler accessed the memory everytime.</p>
  
  <p>So, i don't define volatile any member that modified by multiple threads or modified by only one thread at a time. Am i safe?</p>
  
  <p>Thanks in advance.</p>