pointer escaping return scope bug?

ShadoLight ettienne.gilbert at gmail.com
Fri Nov 25 14:07:28 UTC 2022


On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus wrote:
> On Saturday, 19 November 2022 at 14:07:59 UTC, Nick Treleaven 
> wrote:
>> Hi,
>> The following seems like a bug to me (reduced code, FILE* 
>> changed to int*):
>> ```d
>> @safe:
>>
>> struct LockedFile
>> {
>>     private int* fps;
>>
>>     auto fp() return scope => fps;
>> }
>>
>> void main()
>> {
>>     int* p;
>>     {
>>         auto lf = LockedFile(new int);
>>         p = lf.fp;
>>     }
>>     assert(p != null); // address escaped
>> }
>> ```
>> There's no error with -dip1000.
>> I'll file this unless I overlooked something.
>
> I think this is intended behavior, because you *do* get an 
> error if you replace `new int` with a pointer to a stack 
> variable; e.g.,
>
>     int local;
>     auto lf = LockedFile(&local);
>
> The `return scope` qualifier on the method does *not* mean "the 
> return value of this method is `scope`". It means "this method 
> may return one of this object's pointers, but does not allow 
> them to escape anywhere else." In other words, it lets the 
> compiler determine that the return value of `lf.fp` has *the 
> same* lifetime as `lf` itself.
>
> Since, in your example, `lf` has global lifetime, the compiler 
> deduces that `lf.fp` also has global lifetime, and therefore 
> there is nothing wrong with assigning it to `p`.

I follow your rationale, but for the life of me I cannot see how 
`lf` _"has global lifetime"_.

Looks to me like `lf` is a value instance of the `LockedFile` 
struct (so on the stack) in a local scope inside main. I fully 
agree that the above code is not problematic, but isn't that 
because `p` is declared outside this local scope, and the 
allocation that happens inside the local scope (in the `lf` 
constructor) is on the heap, so the allocation (now assigned to 
`p`) survives the end of the local scope (and the end of the life 
of `lf`) since it is `p` that has global lifetime?

I don't grok how `lf` can survive the local scope. Or am I 
missing something?





More information about the Digitalmars-d-learn mailing list