title: How is this code snippet an example of incorrect synchronization?
body: <p>I am trying to understand the example with incorrect sync code from <a href="https://golang.org/ref/mem" rel="nofollow noreferrer">The Go Memory Model</a>.</p>
  <blockquote>
  <p>Double-checked locking is an attempt to avoid the overhead of synchronization. For example, the twoprint program might be incorrectly written as:</p>
  </blockquote>
  <pre><code>var a string
  var done bool
  
  func setup() {
      a = &quot;hello, world&quot;
      done = true
  }
  
  func doprint() {
      if !done {
          once.Do(setup)
      }
      print(a)
  }
  
  func twoprint() {
      go doprint()
      go doprint()
  }
  </code></pre>
  <blockquote>
  <p>but there is no guarantee that, in <code>doprint</code>, observing the write to done implies observing the write to <code>a</code>. This version can (incorrectly) print an empty string instead of <code>&quot;hello, world&quot;</code>.</p>
  </blockquote>
  <p>What are the detailed reasons for an empty string printed in place of &quot;hello world&quot;? I ran this code about five times, and every time, it printed &quot;hello world&quot;.
  Would the compiler swap a line <code>a = &quot;hello, world&quot;</code> and <code>done = true</code> for optimization? Only in this case, I can understand why an empty string would be printed.</p>
  <p>Thanks a lot!
  At the bottom, I've attached the changed code for the test.</p>
  <pre><code>package main
  
  import(
  &quot;fmt&quot;
  &quot;sync&quot;
  )
  
  var a string
  var done bool
  var on sync.Once
  
  func setup() {
      a = &quot;hello, world&quot;
      done = true
  }
  
  func doprint() {
      if !done {
          on.Do(setup)
      }
      fmt.Println(a)
  }
  
  func main() {
      go doprint()
      go doprint()
      select{}
  }
  </code></pre>