-
Notifications
You must be signed in to change notification settings - Fork 18k
spec: order of evaluation of variables in return statement is not determined #25609
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
Comments
This seems to be working as specified. edit: Oversight, no more I think the above. |
How is this working as specified? This seems to show a discrepancy in the behavior of assigning to a variable depending on whether it's an interface or not. Not trying to be accusatory; just curious what part of the spec covers this. Edit: Better wording. |
Yup, I edited my post while you were writing yours. My apologies. |
There is no guaranteed order, see https://golang.org/ref/spec#Order_of_evaluation |
That seems to specify evaluating of a single expression. The order of evaluation of the expressions in the list of expressions of an return statement seems to be unspecified, so the evaluating I will now stop myself from polluting this issue. I'm no more sure about anything involved in it. |
With Go 1.3 and later I get I think this boils down to when we evaluate variables listed in the return statement. Do we load I don't think the detail of the fact that this is an interface value affects this. It happens to change what the compiler does, but I don't think any specific ordering is required anyhow. |
Test Code: https://play.golang.org/p/xnHqSQyrp_J package main
import "fmt"
func main() {
m, i, j := testChange00()
fmt.Println("retun ", m.(int), i.(int), j.(int)) // 0 0 99
fmt.Println("retun ", m, i, j) // 0 0 99
a, b, c := testChange11()
fmt.Println("retun ", a, b, c) // 2 2 99
}
// return type: int int int Result: 2 2 99
// return type: int int interface{} Result: 2 2 99
// return type: int interface{}, interface{} Result: 2 0 99
// return type: int interface{}, int Result: 2 0 99
// return type: interface{} interface{} interface{} Result: 0 0 99
// return type: interface{} interface{} int Result: 0 0 99
// return type: interface{} int int Result: 0 2 99
// return type: interface{} int interface{} Result: 0 2 99
func testChange00() (interface{}, interface{}, interface{}) {
m := 0
i := 0
f := func() int {
m = 2
i = 2
return 99
}
return m, i, f()
}
func testChange11() (int, int, int) {
m := 0
i := 0
f := func() int {
m = 2
i = 2
return 99
}
return m, i, f()
} |
@KISSMonX that is the reason why I wonder, I think the interface dose affect the result. |
Yeah, indeed affected, but return type should not affect the order of evaluation. |
With the current spec, the order of evaluation is unpredictable. There is no one correct answer, there are several correct answers. Correct Go implementations can produce different results for this program. As I said above, different compilers behave differently today. It may happen that with the current Go 1.10 compiler the order is affected by whether you use an interface type, but future Go releases may well produce different results that are still completely valid. |
I'm closing this issue. The Go spec intentionally defines only a partial ordering on expression evaluation within a statement, and the behaviors demonstrated are all consistent with that (albeit admittedly surprising). So there's no action for us to take here. I think we're open to defining a total ordering (e.g., like Java does and reportedly like C++ is considering), but that needs to take the form of a language spec proposal. |
See also #27804. |
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?go version
go version go1.10.2 darwin/amd64
What did you do?
What did you expect to see?
retun 2 2 99
What did you see instead?
retun 2 0 99
The text was updated successfully, but these errors were encountered: