Hacker News new | ask | show | jobs
by sauerbraten 2126 days ago
I checked out the example code for arrays (https://github.com/betty200744/ultimate-go/blob/3de8a053d9f7...) and noticed that OP seems to misunderstand a few things about Go arrays:

- the cheat sheet differentiates between 'declaring' and 'declaring and initializing', but in Go there are no uninitialized arrays (or slices) - a lot of times in this file, a slice is created instead of an array (lines 18, 21, 25, 31) - arrays in Go don't really have a capacity (it's always the same as the array's length) - the built-ins append and copy as well as the sort functions don't accept arrays (I assume this is why slices are created?)

1 comments

> in Go there are no uninitialized arrays (or slices)

This is a little murky and misleading. In Go, you can actually save memory by 'declaring' only. For example, if you do var x []string, and never use x, it never actually uses memory. Whereas x := []string{} does. The JSON encoder treats the two differently, as well.

Much like the github link, you're confusing slices with arrays. Slices can be nil (data=nil, len=cap=0) or non-nil (data points somewhere, len and cap are what they are), but arrays are just arrays, there's no such thing as an uninitialized [3]byte.
I'm not. I've been a Go programmer for years, and I literally quoted your comment above mine - it says (or slices)
I believe your comment is wrong though. Those two things will use exactly the same amount of memory.

The data pointer in the slice points to an array-type of size zero. All allocations for objects of size zero return a fixed address in the data section (so there is a distinction between a nil and non-nil object, but a pointer to a zero sized object does not actually take any space).

See line 909: https://golang.org/src/runtime/malloc.go

Flip the first line between true and false, you'll see different memory usage based on declaration type. I haven't analyzed the compiler code, but my assumption is it's forced to return an actual slice object when one is declared with :=. But I'd be happy to be better educated here -

https://play.golang.org/p/wVyv0qhj9rp

This is a total red herring.

I don't know why the numbers are consistently different for the different programs, but the compiler is completely optimizing out the function call in both cases.

Consider the example where you do two prints: https://play.golang.org/p/Y1GUutEQkzx

Here is the compiled object code, which is identical for true and false: main.go:15 0x49b640 64488b0c25f8ffffff MOVQ FS:0xfffffff8, CX main.go:15 0x49b649 483b6110 CMPQ 0x10(CX), SP main.go:15 0x49b64d 7624 JBE 0x49b673 main.go:15 0x49b64f 4883ec08 SUBQ $0x8, SP main.go:15 0x49b653 48892c24 MOVQ BP, 0(SP) main.go:15 0x49b657 488d2c24 LEAQ 0(SP), BP main.go:16 0x49b65b 0f1f440000 NOPL 0(AX)(AX*1) main.go:16 0x49b660 e89bfeffff CALL main.printStats(SB) main.go:21 0x49b665 e896feffff CALL main.printStats(SB) main.go:22 0x49b66a 488b2c24 MOVQ 0(SP), BP main.go:22 0x49b66e 4883c408 ADDQ $0x8, SP main.go:22 0x49b672 c3 RET

Notice how there's nothing between the printStats calls?

[]int{} is a non-nil slice, which allocates. The zero-length optimization probably doesn't exist for arrays in this context, because no sane code does this.

This still has nothing to do with "declaring" vs "initializing" (Go makes no such distinction; all values are always "initialized"), or direct use of arrays.