As many of the comments point out it look like this isn't a compiler bug. The example code makes assumptions about the goroutine execution order without using the facilities (e.g. channels) that guarantee the right ordering. The use of atomic doesn't seem to be relevant.
The example code is what I call "works by chance" which I would contrast with code that "works by design". I think some people are trying to argue that a language should prevent developers from writing code that "works by chance" but I don't think that's actually possible. It's the equivalent of saying I want to be able to type anything I want into my editor and have it compile into doing what I think it should do... A "works by design" code here would be adding channel synchronization points between the two goroutines such that the desired execution order is guaranteed.
It's also IMO not reasonable to expect a new compiler to produce identical results to an old compiler. E.g. if the compiler does a better job your code may run faster (or slower) which may break something if you've assumed that something takes so long to run (e.g. some hard coded timeout in some other component).
At least the 1.8 compiler behaviour is deterministic. So code written assuming some particular value of a would either work or fail consistently. Previously you could construct some code that fails randomly.
The example code is what I call "works by chance" which I would contrast with code that "works by design". I think some people are trying to argue that a language should prevent developers from writing code that "works by chance" but I don't think that's actually possible. It's the equivalent of saying I want to be able to type anything I want into my editor and have it compile into doing what I think it should do... A "works by design" code here would be adding channel synchronization points between the two goroutines such that the desired execution order is guaranteed.
It's also IMO not reasonable to expect a new compiler to produce identical results to an old compiler. E.g. if the compiler does a better job your code may run faster (or slower) which may break something if you've assumed that something takes so long to run (e.g. some hard coded timeout in some other component).
At least the 1.8 compiler behaviour is deterministic. So code written assuming some particular value of a would either work or fail consistently. Previously you could construct some code that fails randomly.