去兽医:捕捉内部但不是外部竞争条件

go vet: catches inner but not outer race-condition

中,使用了导致数据争用的嵌套循环。 go vet 只抓住了部分问题。

使用简化版:

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
            }()
        }
    }

Playground

go vet 正确检测到内部竞争条件,但不是外部竞争条件。

这是为什么?太复杂以至于无法跟踪超过 2 层的范围?

一条评论 in the code 说:

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.

go vet命令不会报错o,因为go语句不是o循环中的最后一条语句。

测试非常简单,可能会检测到大多数错误实例。检测错误的其他实例需要一种需要更多时间来开发和执行的方法。

这个 discussion 与 Russ Cox 等人的类似问题。阿尔。很有趣。

特别是这条评论:

... this Issue is more challenging to analyze because it requires proving that the function is not called within the loop, or at least failing to prove that it is called within the loop. Once the anonymous function has been stored in a data structure or passed to another function, vet can no longer precisely determine when it might be called.

In other words, I think the current vet check is probably as good as we can do without interprocedural analysis.