Why is changing a pointer?

Why in this example, changing the pointer.
https://play.golang.org/p/P76IDHg6ZA3
package main

func main() {
 var val int
println(&val)
f(10000)
println(&val)
}

func f(i int) {
 if i--; i == 0 {
return
}
f(i)
}

I assumed that the case and the work of the garbage collector. But even with a disabled garbage collection the pointer changes.

And if you use fmt.Println, the pointer does not change
https://play.golang.org/p/ugjBjFNVO4h
package main

import "fmt"

func main() {
 var val int
println(&val)
f(10000)
println(&val)
fmt.Println(&val)
}

func f(i int) {
 if i--; i == 0 {
return
}
f(i)
}
April 3rd 20 at 18:30
2 answers
April 3rd 20 at 18:32
Solution
By default, the variable val is on the stack, but when using fmt.Println() a variable "escapes" in the heap.
Since the parameters to the function are passed via the stack, and moves the pointer to the variable.
This is clearly seen if you open the debugger and watch the registers change.

Run escape analysis using the command:
go run-gcflags "-m" test.go
$ go run-gcflags "-m" test.go 
# command-line-arguments
./test.go:13:13: inlining yet call to fmt.Println
./test.go:9:6: moved to heap: val
./test.go:13:14: &val escapes to heap
./test.go:13:13: main []interface {} literal does not escape
./test.go:13:13: io.Writer(os.Stdout) escapes to heap
<autogenerated>:1: (*File).close .this does not escape
0xc00001a0a8
0xc00001a0a8
0xc00001a0a8
April 3rd 20 at 18:34
Solution
Goroutines have a few chips in the beginning, and it's not the stack of the thread.
Recursive func f causes an increase stack (in th no TCO and does not seem to be), and preallocate more chips from a different size class (see tcmalloc) with subsequent copying.
The offset of the variable in the stack remains the same but the address has changed.

Well, at fmt.Printf a variable in the heap and permanent address. Like on github was even an explanation for why escape analysis behaves.

Find more questions by tags Go