In a recent question a nested loop was being used that led to a data-race. go vet
only caught some of the problems.
Using a simplified version:
for _, o := range ol {
o := o // <- remove this: `go vet` does *NOT* complain
for _, d := range dl {
d := d // <- remove this: `go vet` will complain
go func() {
fmt.Printf("%03d %03d\n", o, d) // potential data-race
}()
}
}
go vet
correctly detects the inner race-condition, but not the outer one.
Why is this? Too complex to keep track of scopes deeper than 2 levels?
A comment in the code says:
This analyzer checks for references to loop variables from within a function literal inside the loop body. It checks only instances where the function literal is called in a defer or go statement that is the last statement in the loop body, as otherwise we would need whole program analysis.
The go vet
command does not complain about o
because the go statement is not the last statement in the o
loop.
The test is very simple and probably detects most instances of the bug. Detecting other instances of the bug requires an approach that will take more time to develop and execute.