-
Notifications
You must be signed in to change notification settings - Fork 18k
spec: clarify defer semantics #8107
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
Labels
Milestone
Comments
Issue #8109 has been merged into this issue. |
Comment 5 by alan@alandonovan.net: I think we should specify the behaviour one way or another, but my reading of the current spec is that it already does require a specific behaviour: #2, fail upon activation. I don't see any major benefit to specifying behaviour #1 instead, since any programming errors will eventually be detected and reported with certainty during the same execution. |
CL https://golang.org/cl/145960043 mentions this issue. |
Using defer or go with a nil function is sure to be a programming error. I think it's entirely reasonable to panic when the statement is executed rather than when the function is executed. But see also issue #8045. |
The defer statement evalutes fn and args "now" and then executes an actual fn(args) call "later". There is no problem with having a nil fn in Go until you call it. Since the call happens "later", the panic does not happen until "later". I think this is all implied by the current spec but I think it is also fine to say explicitly. I think calling a nil func is roughly analogous to deferring an execution that dereferences a nil argument: func printptrvalue(y *int) { println(*y) } var x *int defer printptrvalue(x) x is not dereferenced until "later". There is no reason the panic should happen "now". Even if the compiler can see that it will panic at execution, the semantics are that the execution happens "later", not "now". My reading of the CL is that it reiterates that the panic for deferring a nil func call happens "later". I agree with that. I have also checked that all versions of Go I can run on my laptop match this behavior (really, they'd have to go out of their way not to): g% cat /tmp/x.go package main import "os" func main() { var f func() defer f() os.Exit(0) } g% go1.1 run /tmp/x.go g% go1.2 run /tmp/x.go g% go1.3 run /tmp/x.go g% go run /tmp/x.go g% This issue was filed as collateral damage from issue #8047, which was that the stack copier didn't work correctly with deferred nil functions. That bug was introduced and fixed during the 1.3 cycle, so deferred nils have worked in all released copies of Go. |
This issue was closed by revision b4eb22d. Status changed to Fixed. |
wheatman
pushed a commit
to wheatman/go-akaros
that referenced
this issue
Jun 25, 2018
Fixes golang#8107. LGTM=iant, rsc, r R=r, rsc, iant, ken CC=golang-codereviews https://golang.org/cl/145960043
wheatman
pushed a commit
to wheatman/go-akaros
that referenced
this issue
Jul 9, 2018
Fixes golang#8107. LGTM=iant, rsc, r R=r, rsc, iant, ken CC=golang-codereviews https://golang.org/cl/145960043
wheatman
pushed a commit
to wheatman/go-akaros
that referenced
this issue
Jul 30, 2018
Fixes golang#8107. LGTM=iant, rsc, r R=r, rsc, iant, ken CC=golang-codereviews https://golang.org/cl/145960043
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
The text was updated successfully, but these errors were encountered: