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.

Reply via email to