Skip to content

cmd/vet: time.Since should not be used in defer statement #60048

Closed
@devoxel

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.

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions