www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Closures and Memory Management

reply Andrew Wiley <wiley.andrew.j gmail.com> writes:
--001485f894245d299404a161b2f5
Content-Type: text/plain; charset=ISO-8859-1

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?
----------
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.

--001485f894245d299404a161b2f5
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I&#39;m working on a project that looks like it&#39;ll need manual memory m=
anagement (the end goal is to get it running on ARM using GDC, where the GC=
 doesn&#39;t seem to behave (that goal might be unrealistic, but I can hope=
)), and I&#39;m trying to figure out how to deal with closures. My understa=
nding is that a closure is a function pointer and the enclosing scope, whet=
her that scope is variables that are copied into the closure or a class ins=
tance to use as &quot;this.&quot; Is this correct?<div>

<br></div><div>Assuming that&#39;s correct, this would involve a memory all=
ocation, right?</div><div>----------</div><div>class Test {</div><div>void =
doStuff() {}</div><div>}</div><div><br></div><div>void doSomethingElse(void=
 delegate() thing) {</div>

<div>thing();</div><div>}</div><div><br></div><div>void main() {</div><div>=
auto test =3D new Test();</div><div>doSomethingElse(&amp;test.doStuff);</di=
v><div>}</div><div>----------</div><div><br></div><div>My understanding is =
that as soon as I run &quot;&amp;test.doStuff&quot; a closure is generated.=
 Is this correct? Would it then be valid, in doSomethingElse, to run &quot;=
GC.free(thing)&quot; ?</div>

<div><br></div><div>Any insight would be appreciated.</div>

--001485f894245d299404a161b2f5--
Apr 20 2011
next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Wed, 20 Apr 2011 19:07:43 -0400, Andrew Wiley  
<wiley.andrew.j 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); }
Apr 20 2011
prev sibling next sibling parent reply "Eric Poggel (JoeCoder)" <dnewsgroup2 yage3d.net> writes:
On 4/20/2011 7:07 PM, Andrew Wiley 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))

I wonder if it would be useful to have a "static" phobos project, a subset/replacement of standard library functions that can behave without a garbage collector. Are there enough situations D is a good fit but garbage collection is not?
Apr 20 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-04-21 03:37, Eric Poggel (JoeCoder) wrote:
 On 4/20/2011 7:07 PM, Andrew Wiley 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))

I wonder if it would be useful to have a "static" phobos project, a subset/replacement of standard library functions that can behave without a garbage collector. Are there enough situations D is a good fit but garbage collection is not?

I would guess, as he mentioned, ARM i.e. mobile devices. Of course you could use a garbage collector on a mobile device but, for example, iOS doesn't use one, even though Mac OS X has a built in garbage collector. -- /Jacob Carlborg
Apr 20 2011
prev sibling parent Steven Wawryk <stevenw acres.com.au> writes:
The requirement to use manual memory management and *not* have a garbage 
collector is the rule rather than the exception in the domains of 
embedded and OS development.

You'll often hear in these groups that you "can turn the GC off", but 
that's not actually true.  The GC *can* be disabled (intended to be 
temporary) to prevent collection cycles during critical pieces of code, 
but to not use it at all is not a serious option.  The GC is used to 
allocate memory extensively in language features and in Phobos, and to 
avoid using those leaves a severely lobotomised subset.  Language 
features that allocate through the GC are documented at:

http://www.digitalmars.com/d/2.0/garbage.html

but there is no documentation that I know of that lists the parts of 
Phobos that you can't use without the GC.

Given all the nice things about D I would love to have a RAII option as 
a first class option that lets you plug in the memory manager you choose 
but I don't think it's going to happen.  I don't remember where I read 
it, but I remember reading somewhere that this won't happen because to 
write libraries that can be used with either GC or RAII requires that 
they be written for RAII, ie with explicit delete's in destructors etc, 
and that's been rejected as a possibility for the language and Phobos.

Unfortunately, I would have to say that for applications and domains in 
which you require no garbage collection then D is not a serious option.


On 21/04/11 08:37, Andrew Wiley 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?
 ----------
 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.

Apr 26 2011