Escape analysis (full scope analysis proposal)

Steven Schveighoffer schveiguy at yahoo.com
Sat Nov 1 09:00:10 PDT 2008


"Michel Fortin" wrote
> If you can't determine yourself that a function can work with scoped 
> parameters, you'd better never call that function with reference to local 
> variables and leave its prototype with noscope parameters, making the 
> compiler aware of the situation.
>
> In any case, the one who design the function is the one who is most likely 
> able to tell you whether or not it accepts scoped arguments. The current 
> situation makes the caller of that function responsible of calling it 
> correctly. I think that's backward.

But often times, the safety of the call depends on how it is being called. 
Unless the function has fully documented the scope escapes of its 
parameters, which as I have been saying, is going to be difficult, or 
impossible, for a person to figure out.

>> The only way I can see to solve this is to do it at link time.  When you
>> link, piece together the parts of the graph that were incomplete, and see 
>> if
>> they all work.  It would be a very radical change, and might not even 
>> work
>> with the current linkers.  Especially if you want to do shared libraries,
>> where the linker is builtin to the OS.
>
> I think you're dreaming... not that it's a bad thing to have ambition, but 
> that's probably not even possible.

Sure it is ;)  You have to write a special linker.

I think everyone who thinks a scope decoration proposal is going to 1) solve 
all scope escape issues and 2) be easy to use is dreaming :P

>>> So, without a way to specify the requested scope of the parameters, 
>>> you'll
>>> very often have holes in your escape analysis that will propagate down 
>>> the
>>> caller chain, preventing any useful conclusion.
>>
>> Yes, and if a function has mis-specified some of its parameters, then you
>> have code that doesn't compile.  Or the function itself won't compile, 
>> and
>> you need to do some more manual analysis.  Imagine a function that calls 
>> 5
>> or 6 other functions with its parameters.  And there are multiple 
>> different
>> dependencies you have to resolve.  That's a lot of analysis you have to 
>> do
>> manually.
>
> You'll get an error at some call site, which can mean only two things: 
> either your local variable shouldn't be bound to the local scope (because 
> the function expects a reference it can keep beyond its scope) so you 
> should allocate it on the heap, or the function you're calling has its 
> prototype wrong.

Or, the prototype can't be written correctly, even though it is provable 
that no escapes occur.

>>> I don't think it's bad to force interfaces to be well documented, and
>>> documented in a format that the compiler can understand to find errors
>>> like this.
>>
>> I think this concept is going to be really hard for a person to decipher,
>> and really hard to get right.
>
> It takes some thinking to get the prototype right at first. But it takes 
> less caution calling the function later with local variables since the 
> compiler will either issue an error or automatically fix the issue by 
> allocating on the heap when an argument requires a greater scope.

I hope to avoid this last situation.  Having the compiler make decisions for 
me, especially when heap allocation occurs, is bad.

>> void f(ref int *a, int *b, int *c) { if(*b < *c) a = b;  else a = c;}
>
> void f(scope ref int *a, scopeof(a) int *b, scopeof(o) int *c)
> {
> if (*b < *c) a = b; else a = c;
> }

I assume you meant scopeof(a) instead of scopeof(o), but in any case, your 
design is incorrect.  a depends on b and c's scope, not the other way 
around.

Consider this valid usage:

void foo()
{
   int b = 1, c = 2;
   bar(&b, &c);
}

void bar(scope int *b, scope int *c)
{
   int *a;
   f(a, b, c);// should not fail, but would with your decorations
}

-Steve 





More information about the Digitalmars-d mailing list