-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
cmd/compile: different behaviors between short and normal variable declarations #36449
Comments
It looks the output of the short declaration case behaves the same as pure assignments: func foo() {
var x int
var y, z int
y, z = x, f(&x)
fmt.Println(y, z) // 123 123
} |
It looks like this is because dcl.go:variter emits N:N variable declaration+initialization statements as On the other hand, for As @go101 points out, the discrepancy is still conforming to the Go spec, so it's not something we have to fix. I suspect the easiest fix (assuming we think it's worth fixing) would be changing variter to emit a single OAS2 node instead of multiple OAS nodes. I'm a little nervous if this has any unintended consequences via Another question is if it has any effect on compiler performance or on compiled program performance. I haven't looked into these at all yet. |
I tried with a simple patch:
With this,
|
Is it ok for compilers to automatically convert all local normal variable declarations to short variable declarations? |
That's what my patch above does:
|
It looks the results become consistent with tip. |
Another similar case is found: package main
func p() {
f := func(x int) { print(x) }
g := func() int { f = nil; return 1 }
defer f(g())
}
func q() {
f := func(x int) { print(x) }
g := func() int { f = nil; return 1 }
f(g())
}
func main() {
p()
q()
} [edit]: an modified example which includes package main
func h() {
c := make(chan int)
f := func(x int) { print(x); <-c }
g := func() int { f = func(int) { print(9); <-c }; return 1 }
go f(g())
c <- 1
}
func p() {
f := func(x int) { print(x) }
g := func() int { f = func(int) { print(9) }; return 1 }
defer f(g())
}
func q() {
f := func(x int) { print(x) }
g := func() int { f = func(int) { print(9) }; return 1 }
f(g())
}
func main() {
h() // 1
p() // 1
q() // 9
} |
@go101 Sorry, how does that last test case demonstrate a difference in semantics between normal and short variable declarations? |
It is not variable declaration related. It is related to this issue in the expression evaluation order consistency view. |
This comment was marked as outdated.
This comment was marked as outdated.
This issue can be closed now. Because the cases mentioned in #36449 (comment) now print consistent outputs now. |
This issue is filed per @mdempsky's suggestion.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What did you do?
What did you expect to see?
Same outputs for the two functions.
What did you see instead?
Different outputs.
This is an inconsistency in gc, though it looks this doesn't violate Go spec, as some expression evaluation orders in Go are unspecified. But maybe it would be great to make the outputs in this examples consistent.
[edit]: this inconsistency has been removed since Go toolchain 1.20. But another found one still exists.
The text was updated successfully, but these errors were encountered: