Function scope arguments
Timon Gehr
timon.gehr at gmx.ch
Tue Jan 15 08:12:41 PST 2013
On 01/15/2013 04:03 PM, Artur Skawina wrote:
> On 01/15/13 15:09, Timon Gehr wrote:
>> On 01/15/2013 01:44 PM, Artur Skawina wrote:
>>> On 01/15/13 12:48, deadalnix wrote:
>>>> On Tuesday, 15 January 2013 at 10:58:17 UTC, Artur Skawina wrote:
>>>>> Different problem - lifetime. One approach would be to disallow escaping
>>>>> them (which in this case includes returning them) unless the compiler is
>>>>> able to do the right - ie the body of the function is available. Somewhat
>>>>> unorthodox, but could work. (The problem are not the trivial cases; it's the
>>>>> ones where the compiler has no idea which ref is escaped/returned at runtime)
>>>>>
>>>>
>>>> The compiler should assume they may escape unless scope is specified.
>>>
>>> This is about /avoiding/ "hidden" heap allocations as much as possible. Having
>>> functions with 'ref' and 'auto-ref' args always trigger them is not ideal.
>>>
>>> 'lazy' args are already problematic enough. (there's currently no way to mark
>>> them as non-escaping, the compiler has to assume that the do -> the result is
>>> that they /always/ cause heap allocations and you have to use explicit scoped
>>> delegates instead, losing the syntax advantages)
>>
>> Actually lazy args are implicitly 'scope' and never allocate.
>
> I wish. :)
>
> Seriously though, I don't.
Me neither, but that is what happens.
> They can be escaped and they do allocate. They have to. The problem is just
> that there currently is no way to tell the compiler i-know-what-i'm-doing
> and avoid the heap allocated closures.
>
No, there is no way to get a heap allocated closure from a lazy parameter.
> [if the behavior changed in newer (than my old gdc) compiler versions then such a
> change is bogus, as it would mean that stack objects could be escaped]
>
> artur
>
I think the behaviour has always been the same (at least with DMD).
import std.stdio;
int delegate() foo(lazy int x){
return ()=>x;
}
int delegate() escape(int x){
return foo(x);
}
void trash(){
int[2] x=1337;
}
void main(){
auto dg = escape(2);
trash();
writeln(dg());
}
$ dmd -run tt.d
1337
$ gdmd -run tt.d
-1430461920
If the behaviour was as you suggest, the output would be:
2
More information about the Digitalmars-d
mailing list