FWIW, I believe the crux here is that `y` itself escapes, not the pointee of `y`. The pointee escapes as well, but it's printed as `n moved to heap`. The close then closes over `y` (not over `*y`), meaning it needs to store a pointer to `y` as well. That is, I assume, why `y` escapes. However, I'm not sure - I don't understand all the details of how escape analysis works (and it is constantly changing, so it doesn't seem worthwhile to learn it).
I think to prove that `y` does not escape, you'd likely have to prove that the Go routine stops using `y` before the `println(&y)` is executed. I don't think it's reasonable to expect the compiler to prove that. In other words: There might be an argument that `y` doesn't escape, but I don't believe it's reasonable to expect the compiler to prove so. There will always be such cases. I can't imagine a convincing argument that this one is a critical one to solve. On Tue, Jun 1, 2021 at 4:53 PM tapi...@gmail.com <tapir....@gmail.com> wrote: > Thanks for the explanations. I agree on them mostly. > But the println call doesn't make x escape, so I think println is not the > root cause making y escape. > In fact, I'm surprised that y doesn't escape without the last println call. > It looks gc is so smart that it translates "*y" to the value referenced by > y at compile time. > However, with the last println call, gc becomes less smart by disabling > the translation. > The following is the instructions generated for "*y++" with and without > the last println call. > > // Without the last println call. > 0x001d 00029 (main.go:12) MOVQ "".y+24(SP), AX > 0x0022 00034 (main.go:12) INCQ (AX) > > // With the last println call. > 0x001d 00029 (main.go:12) MOVQ "".&y+24(SP), AX > 0x0022 00034 (main.go:12) MOVQ (AX), AX > 0x0025 00037 (main.go:12) INCQ (AX) > > On Tuesday, June 1, 2021 at 10:26:04 AM UTC-4 Jan Mercl wrote: > >> On Tue, Jun 1, 2021 at 3:52 PM tapi...@gmail.com <tapi...@gmail.com> >> wrote: >> >> By default, any local variable that has its address taken and that >> address can outlive the function execution forces the variable to >> escape, quite naturally as the stack frame with the variable is >> destroyed upon returning from the function. >> >> Then there are, or could be, some special cases, where the compiler >> can prove it is not necessary. It's possible the compiler cannot prove >> much about a special function like 'println` that may, for example, >> never exists in SSA form etc. >> >> The last statement in main can be somewhat special wrt escape >> analysis, but that depends on implementation details, so in the >> general case the answer to the topic question is IMO 'yes'. >> > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/81f0e194-5e74-44e8-978c-f02749da6f59n%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/81f0e194-5e74-44e8-978c-f02749da6f59n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfFkrfkEr-2T2dcP%3D3R5k0uwgNv%3DHe9vYun5dt5ocpqEXA%40mail.gmail.com.