-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
AnalysisIssues related to static analysis (vet, x/tools/go/analysis)Issues related to static analysis (vet, x/tools/go/analysis)FrozenDueToAgeProposalProposal-Accepted
Milestone
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.
twmb, ShoshinNikita, willfaught, ainar-g, martin-sucha and 5 more
Metadata
Metadata
Assignees
Labels
AnalysisIssues related to static analysis (vet, x/tools/go/analysis)Issues related to static analysis (vet, x/tools/go/analysis)FrozenDueToAgeProposalProposal-Accepted