Reputation: 73
I'm trying to understand how this case is processed by escape analysis, it behaves differently when a field in structs is set on struct initialization and when it's set after struct initialization. Here's the code:
type X struct {
p *int
}
func main() {
var i1 int
x1 := &X{
p: &i1,
}
_ = x1
var i2 int
x2 := &X{}
x2.p = &i2
}
Output of go build -gcflags="-m -m -m"
:
./main.go:7:6: can inline main with cost 31 as: func() { var i1 int; i1 = <nil>; x1 := &X{...}; _ = x1; var i2 int; i2 = <nil>; x2 := &X{}; x2.p = &i2 }
./main.go:8:6:[1] main stmt: var i1 int
./main.go:8:6:[1] main stmt: i1 = <nil>
./main.go:9:5:[1] main stmt: x1 := &X{...}
./main.go:9:2:[1] main stmt: var x1 *X
./main.go:12:4:[1] main stmt: _ = x1
./main.go:14:6:[1] main stmt: var i2 int
./main.go:14:6:[1] main stmt: i2 = <nil>
./main.go:15:5:[1] main stmt: x2 := &X{}
./main.go:15:2:[1] main stmt: var x2 *X
./main.go:16:7:[1] main stmt: x2.p = &i2
./main.go:14:6: i2 escapes to heap:
./main.go:14:6: flow: {heap} = &i2:
./main.go:14:6: from &i2 (address-of) at ./main.go:16:9
./main.go:14:6: from x2.p = &i2 (assign) at ./main.go:16:7
./main.go:14:6: moved to heap: i2
./main.go:9:8: &X{...} does not escape
./main.go:15:8: &X{} does not escape
So why does i2
escape to heap? I guess it has something to do with the fact that compiler can't determine a lifetime of a variable at compile time. Though I don't understand why it is so.
Upvotes: 0
Views: 204