Closed
Description
What version of Go are you using (go version
)?
$ go version go version go1.16.4 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 GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/Users/joao/Library/Caches/go-build" GOENV="/Users/joao/Library/Application Support/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/joao/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="darwin" GOPATH="/Users/joao/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/Cellar/go/1.16.4/libexec" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/Cellar/go/1.16.4/libexec/pkg/tool/darwin_amd64" GOVCS="" GOVERSION="go1.16.4" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/dev/null" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/2d/wcw2b3c57jz69cl5tg_s2fx00000gn/T/go-build3928827666=/tmp/go-build -gno-record-gcc-switches -fno-common" GOROOT/bin/go version: go version go1.16.4 darwin/amd64 GOROOT/bin/go tool compile -V: compile version go1.16.4 uname -v: Darwin Kernel Version 21.3.0: Wed Jan 5 21:37:58 PST 2022; root:xnu-8019.80.24~20/RELEASE_X86_64 ProductName: macOS ProductVersion: 12.2.1 BuildVersion: 21D62 lldb --version: lldb-1103.0.22.10 Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
What did you do?
I have a package consisting of the following two files:
f1.go
package main
var A int = 3
var B int = A + 1
var C int = A
f2.go
package main
import "fmt"
var D = f()
func f() int {
A = 1
return 1
}
func main() {
fmt.Println(A, B, C)
}
What did you expect to see?
According to the Go language specification, "package-level variable initialization proceeds stepwise, with each step selecting the variable earliest in declaration order which has no dependencies on uninitialized variables".
As such, I would expect two possible orders in which the global variables can be initialized:
- A < B < C < D - happens when you compile the project by passing f1.go first to the compiler, followed by f2.go . In this case, the output is "1 4 3"
- A < D < B < C - happens when f2.go is passed first to the compiler. In this case, the expected output would be "1 2 1".
What did you see instead?
For the second case (when f2.go is passed first), the actual output is "1 2 3". If instead I rewrite file f1.go to the following, I get the expected output for case 2.
Rewritten f2.go
package main
import "fmt"
var A int = initA()
var B int = initB()
var C int = initC()
func initA() int {
fmt.Println("Init A")
return 3
}
func initB() int {
fmt.Println("Init B")
return A + 1
}
func initC() int {
fmt.Println("Init C")
return A
}
Output
Init A
Init B
Init C
1 2 1
Additional Information
This issue was first discussed in the golang-nuts Google Group (link).
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Done