Odd Behavior (different results when running vs debugging)

package main

import (
	"fmt"
)

var x int32 = 1

func main() {
	go foo()
	for {
		fmt.Printf("%d\n", x)
	}
}

func foo() {
	for i := 0; ; i++ {
		if i%2 == 0 {
			x = 2
		} else {
			x = 3
		}
	}
}

You are running two tight loops in parallel. The order of execution is arbitrary and can change each time. If both are executed by different system threads, the operating system scheduler will determine the order and priority of execution. They may run on different cores or on the same core.
Concurrent access to the same variable is not safe from two concurrent go routines - if you run the code with -race you will get a warning.

Since there is no safe before/after for the access of X the compiler may be optimizing and caching the value of X locally as an loop invariant - thus the loop assumes X will stay 1 forever and just print 1 forever (which is correct behavior for the spec)

I think the debugger may not use this optimization and therefore you are “lucky” to get a random string of 2/3 in the output.

2 Likes

Thank you very much for your detailed answer

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.