go version)?go version go1.9.3 linux/amd64
yes
a.go:
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello, playground")
const k uint64 = 1 << 30
_ = []int{k:1}
}}
go build a.go
produce a binary in one second.
computer becomes lagging, almost hanging.
I must press CTRL-C for several times to stop the building.
I can reproduce the issue with go version go1.9.3 linux/amd64 when replacing the final }} with } to make the code syntactically valid.
The hang may be caused by my computer (8G memory) has not enough memory.
But I think this should only happen at run time, not compile time.
If I change the slice element type to byte, it fails to compile with the following error:
./a.go:10:15: prepwrite: bad off=1073741824 siz=1 s="".statictmp_1
You are trying to create a slice of 1073741824 integers. Which would mean you are trying to get 1073741824 * 8 bytes = 8GB of memory approximately.
Yes. But I think the hang should occur at run time, instead of compile time.
The second issue you reported (the fact that with byte the compiler just prints
./a.go:10:15: prepwrite: bad off=1073741824 siz=1 s="".statictmp_1
) looks more serious.
I suspect it would do the same thing with int64 on a machine with enough memory.
I changed the issue's title to highlight the linker(?) crash you reported in your second post, since I believe it is more interesting that your machine getting slow on the program having the int64 array.
I think it is to do with the way the slice is being initialized. []int{k:1} creates a slice of 0,0,...1. But if you change the code to make([]int, k) everything works fine. Frankly, I have never seen syntax like this - []int{k:1}.
FTR: foo := []T{n:1} makes foo with n+1 elements in contrast to foo := make([]t, n).
Note to the compiler guys: I guess the compiler tries to be nice wrt to initialization time and puts the images for composite literals in the text and/or data segments - triggering this issue. If that's the case I think the solution would be to detect when the composite literal is very sparse/mostly zero-values and perform instead a run time all-zero value creation and initialization of the non zero-valued items only all in code.
/cc @griesemer @mdempsky @josharian
@cznic Yes, the compiler could probably be a bit smarter here - on the other hand, perhaps one shouldn't write code like this. But I agree that the compiler shouldn't just appear to be hanging.
To summarize:
1) $ go tool compile x.go
x.go:4:22: prepwrite: bad off=1073741824 siz=1 s="".statictmp_0
for x.go:
package p
func f() {
_ = []byte{1 << 30: 0}
}
2) $ go tool compile x.go
x.go:4:21: prepwrite: bad off=8589934592 siz=8 s="".statictmp_0
for x.go (same as above, but int instead of byte):
package p
func f() {
_ = []int{1 << 30: 0}
}
3) There's no issue with:
package p
var X = []int{1 << 30: 0}
Not urgent. Moving to 1.12.
Related to #27447
Change https://golang.org/cl/151319 mentions this issue: cmd/compile: initialize sparse slice literals dynamically
Most helpful comment
Yes. But I think the hang should occur at run time, instead of compile time.