Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/blog: defer statements execute before/after the caller returns #45889

Open
howardtw opened this issue Apr 30, 2021 · 5 comments
Open

x/blog: defer statements execute before/after the caller returns #45889

howardtw opened this issue Apr 30, 2021 · 5 comments
Labels
Documentation help wanted NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@howardtw
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.16.2 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

What did you do?

In this example the defer function doesn't change the returned value whereas using the named return values would do the trick in this example.

If the defer function is executed after the caller returns as this blog post suggests, that would explain it. However, the doc says defer functions are executed before the caller returns.

What did you expect to see?

The blog post and the Golang doc being consistent.

What did you see instead?

The blog post says the list of saved calls is executed after the surrounding function returns whereas the Golang doc says the list of saved calls is executed before the surrounding function returns

@howardtw howardtw changed the title doc: defer statements execute after the caller doc: defer statements execute after the caller returns Apr 30, 2021
@leighmcculloch
Copy link
Contributor

Is this a case that go vet could provide an error for?

If a deferred function writes to a variable defined in the surrounding functions scope that has already returned, it seems to me like that is likely an error.

@seankhliao
Copy link
Member

The spec says

deferred functions are executed after any result parameters are set by that return statement but before the function returns to its caller.

which is a more accurate representation of what's happening.

this might not pass the accuracy bar for cmd/vet, ex #8220

@ianlancetaylor ianlancetaylor added help wanted NeedsFix The path to resolution is known, but the work has not been done. labels Apr 30, 2021
@ianlancetaylor ianlancetaylor added this to the Backlog milestone Apr 30, 2021
@ianlancetaylor
Copy link
Contributor

I think we could reasonably tweak the blog entry to make it slightly more accurate (cc @adg since he wrote the blog post).

@seankhliao seankhliao changed the title doc: defer statements execute after the caller returns x/blog: defer statements execute before/after the caller returns Apr 30, 2021
@adg
Copy link
Contributor

adg commented May 2, 2021

Happy to review any amendments to the blog post.

@guodongli-google
Copy link

guodongli-google commented May 10, 2021

An individual vet check for this pattern seems to be an overkill for the reason mentioned in #8220. A more general check is to examine whether the writes within defer are used or not. In this example, b = 2 is not used (by the return) so this is suspicious. If b is a named return value then it is used by "return b". Of course the checker shall know about the correct control flow, e.g. "deferred functions are executed after any result parameters are set by that return statement but before the function returns to its caller".

func f() int {
    b := 1
    defer func() {
        b = 2
    }()
   return b
}

This may be added as an extension of the "unusedwrite" checker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

7 participants