I am trying to understand the example with incorrect sync code from [The Go Memory Model](https://golang.org/ref/mem).

> 
> Double-checked locking is an attempt to avoid the overhead of synchronization. For example, the twoprint program might be incorrectly written as:
> 
> 
> 

```
var a string
var done bool

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        once.Do(setup)
    }
    print(a)
}

func twoprint() {
    go doprint()
    go doprint()
}

```

> 
> but there is no guarantee that, in `doprint`, observing the write to done implies observing the write to `a`. This version can (incorrectly) print an empty string instead of `"hello, world"`.
> 
> 
> 

What are the detailed reasons for an empty string printed in place of "hello world"? I ran this code about five times, and every time, it printed "hello world".
Would the compiler swap a line `a = "hello, world"` and `done = true` for optimization? Only in this case, I can understand why an empty string would be printed.

Thanks a lot!
At the bottom, I've attached the changed code for the test.

```
package main

import(
"fmt"
"sync"
)

var a string
var done bool
var on sync.Once

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        on.Do(setup)
    }
    fmt.Println(a)
}

func main() {
    go doprint()
    go doprint()
    select{}
}

```