I don't quite get why Go's escape analysis says that a local integer variable escapes to the heap when it is passed to fmt.Fprintln while it is not escaping when it is passed to another self-written function with the same signature as fmt.Fprintln. I hope the two scenarios A and B below should make the problem more clear.
Scenario A: x escapes to heap
Take the following content of main.go:
package main
import (
"fmt"
"os"
)
func main() {
x := 73
fmt.Fprintln(os.Stdout, x)
}
When you now run go build -gcflags "-m" you see an output that indicates that the x escapes to the heap. The output says something along the lines of
...
.\main.go:10:14: x escapes to heap
...
Scenario B: x does not escape to heap
Now take the following content of main.go:
package main
import (
"io"
"os"
)
func main() {
x := 73
myOwnPrintFunction(os.Stdout, x)
}
//go:noinline
func myOwnPrintFunction(w io.Writer, a ...interface{}) {
println(a)
}
Running go build -gcflags "-m" again you see an output that indicates that x no longer escapes to the heap. The output now says something along the lines of
...
.\main.go:10:20: x does not escape
...
I don't get the difference here. I would have thought that scenario A is correct since x is passed to a variadic function that accepts an arbitrary number of interface{} arguments. But apparently that's wrong since the variable no longer escapes when it is passed to the self-written function myOwnPrintFunction which is also a variadic function accepting an arbitrary number of interface{} arguments and where the compiler is instructed to not inline this simple function.