cmd/vet: time.Since should not be used in defer statement #60048
Closed
Description
Background
func main() {
start := time.Now()
defer fmt.Println(time.Since(start))
time.Sleep(1 * time.Second)
}
People unfamiliar to the intricacies of the defer statement might expect that this code will print 1s, but it prints 0s. (See on go playground).
A correct version is:
func main() {
start := time.Now()
defer func() { fmt.Println(time.Since(start)) }()
time.Sleep(1 * time.Second)
}
This is expected behaviour, but seems to be a somewhat common gotcha. I've made the mistake on a few occasions. I did a search with github codesearch and I found several instances where this is happening in public repositories, some examples:
Summary
I can't think of many use-cases where one calls defer f(time.Since(t))
and intends the behaviour to work as it does. I propose that a vet check is added to disallow this case.
I have implemented an analyser that does this already BTW but the guidelines indicate I should open an issue first for discussion.