www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Alias delegates and nogc

reply Ivan Timokhin <timokhin.iv gmail.com> writes:
With dmd 2.066.1, this compiles:

void bar(scope int delegate() a)  nogc {}

void foo(int x)  nogc
{
    bar(() => x);
}

but this doesn't:

void bar(alias a)() {}

void foo(int x)  nogc
{
    bar!(() => x)();
}

Fails with
Error: function test.foo  nogc function allocates a closure with the GC

Is there any way to pass a delegate that:
1. avoids indirect calls (like alias);
2. does not allocate (like scope delegate);
3. captures local variables?
Feb 18 2015
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Wed, 18 Feb 2015 19:09:50 +0300, Ivan Timokhin wrote:

 Is there any way to pass a delegate that:
 1. avoids indirect calls (like alias);
 2. does not allocate (like scope delegate);
 3. captures local variables?
i don't think that you can do it. but what is wrong with delegate=20 version? it doesn't really cost *that* much (especially if you'll=20 remember that DMD optimiser is far from... well, optimal ;-), and if you=20 really doing something where indirect function call matters, you'd better=20 use mixins anyway.=
Feb 18 2015
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Wed, 18 Feb 2015 18:13:58 +0000, ketmar wrote:

 it doesn't really cost *that* much (especially if you'll
 remember that DMD optimiser is far from... well, optimal ;-)
i mean that there are alot of other code that isn't optimal for speed, so=20 delegate call is rarely an issue.=
Feb 18 2015
prev sibling parent Ivan Timokhin <timokhin.iv gmail.com> writes:
ketmar wrote:

 On Wed, 18 Feb 2015 19:09:50 +0300, Ivan Timokhin wrote:
 
 Is there any way to pass a delegate that:
 1. avoids indirect calls (like alias);
 2. does not allocate (like scope delegate);
 3. captures local variables?
i don't think that you can do it. but what is wrong with delegate version? it doesn't really cost *that* much (especially if you'll remember that DMD optimiser is far from... well, optimal ;-), and if you really doing something where indirect function call matters, you'd better use mixins anyway.
Thank you for the answer, I suspected as much.
Feb 18 2015
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/18/15 11:09 AM, Ivan Timokhin wrote:
 With dmd 2.066.1, this compiles:

 void bar(scope int delegate() a)  nogc {}

 void foo(int x)  nogc
 {
      bar(() => x);
 }

 but this doesn't:

 void bar(alias a)() {}

 void foo(int x)  nogc
 {
      bar!(() => x)();
 }

 Fails with
 Error: function test.foo  nogc function allocates a closure with the GC

 Is there any way to pass a delegate that:
 1. avoids indirect calls (like alias);
 2. does not allocate (like scope delegate);
 3. captures local variables?
Building on ketmar's point, I think you should not worry about tricking the compiler into avoiding indirect calls. The compiler could and should avoid indirect calls and GC closures when it can do so. In particular, it should be able to inline bar, and (I assume in a full version of the code) any uses of the delegate. But it just doesn't yet. -Steve
Feb 18 2015