Closures and Memory Management

Robert Jacques sandford at jhu.edu
Wed Apr 20 18:20:26 PDT 2011


On Wed, 20 Apr 2011 19:07:43 -0400, Andrew Wiley  
<wiley.andrew.j at gmail.com> wrote:

> I'm working on a project that looks like it'll need manual memory  
> management
> (the end goal is to get it running on ARM using GDC, where the GC doesn't
> seem to behave (that goal might be unrealistic, but I can hope)), and I'm
> trying to figure out how to deal with closures. My understanding is that  
> a
> closure is a function pointer and the enclosing scope, whether that  
> scope is
> variables that are copied into the closure or a class instance to use as
> "this." Is this correct?
>
> Assuming that's correct, this would involve a memory allocation, right?

No to allocation, yes to 'correct'.

> ----------
> class Test {
> void doStuff() {}
> }
>
> void doSomethingElse(void delegate() thing) {
> thing();
> }
>
> void main() {
> auto test = new Test();
> doSomethingElse(&test.doStuff);
> }
> ----------
>
> My understanding is that as soon as I run "&test.doStuff" a closure is
> generated. Is this correct? Would it then be valid, in doSomethingElse,  
> to
> run "GC.free(thing)" ?
>
> Any insight would be appreciated.

I'd recommend looking at D's ABI page  
(http://www.digitalmars.com/d/2.0/abi.html). Basically a delegate can be  
one of two things. A) {an object, member function pointer} or B) {context  
pointer, function pointer}
In the your example above, &test.doStuff creates a delegate of type A.  
These don't require any memory allocation, (beyond the original class  
allocation). An example that would require allocation would be:
void main() {
     int x = 0;
     doSomethingElse({x++;});
     assert(x==1);
}

However, you can also declare a delegate with scope to prevent this: (i.e.  
to use stack instead of heap allocation)

void main() {
     int x = 0;
     scope dg = (){x++;};
     doSomethingElse(dg);
}


More information about the Digitalmars-d mailing list