-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: package-level variable initialization with constant dependencies doesn't match order specified in Go spec #66575
Comments
If we place const declaration block before var declaration block, the init order will become v0 -> v1 -> v2:
|
constInitCheck() has a dependency on c1 and c2, which are uninitialized at that point. |
@seankhliao thanks for instant reply. Go spec says "no dependencies on uninitialized variables" , but c1 and c2 are uninitialized constants. there is a little bit of inconsistency. |
This looks like it changed between 1.21 and 1.22. |
Change https://go.dev/cl/575075 mentions this issue: |
Bisect points to https://go-review.googlesource.com/c/go/+/517617, switching to use types2 for init order, which makes sense. types2 always had this bug. |
[edit]: BTW, should this be backported? As it may cause some wrong initial values: https://go.dev/play/p/2HA4DR3_cjD Just a curious BTW question: why is package main
var x = 0
var a = foo()
var b = x
func foo() int {
x++
return x
}
func main() {
println(a, b) // 1 0
} |
@go101 Thanks. Would you mind opening a separate issue for that? The gc compiler prints |
Reopening for @griesemer to decide if anything needs to change in the spec. @go101 I don't think this issue warrants backporting. The workaround is pretty easy. |
@go101 Re: your question about this code: package main
var x = 0
var a = foo()
var b = x
func foo() int {
x++
return x
}
func main() {
println(a, b) // 1 1 for Go 1.23
} The result should be 1 1: With respect to the original issue, constants are never "initialized", they have their values already at compile time. The bug was fixed with CL 575075. (Technical aside: constants appear in the implementation code determining initialization order only because that code is also used to detect invalid cycles among constant declarations; constants don't have an impact on initialization order. The bug was that constants were treated like variables w/o dependencies and thus their source order influenced the initialization order. The fix was to prioritize a constant always before any variable which effectively removes them from the initialization order - they are "pre-initialized" if you will.) With respect to the spec: I don't think anything needs to change. The spec explicitly talks about variables, not constants in this context. With respect to backporting: I think we should backport this. It's easy enough and it is a bug with respect to the spec. Closing this issue as fixed but will create a backport issue. |
@gopherbot please consider this for backport to 1.22, it's a bug with respect to the spec. |
Backport issue(s) opened: #67820 (for 1.22). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
Go version
go 1.22.0
Output of
go env
in your module/workspace:What did you do?
I have example below:
What did you see happen?
Compile and run the code in go 1.22.0,I got this output:
What did you expect to see?
According to the latest go spec:
v0、v1 and v2 all have initializaiton expression , and should be considered as "not ready for initialization"。their init order should be v0 -> v1 -> v2。but the real init order is v1 -> v2 -> v0。
The text was updated successfully, but these errors were encountered: