Heap fucntion calls
Simen Kjaeraas
simen.kjaras at gmail.com
Wed Sep 21 10:56:33 PDT 2011
On Wed, 21 Sep 2011 18:32:49 +0200, deadalnix <deadalnix at gmail.com> wrote:
> D has a wonderfull feature named delegate. Delegate can acess local
> data, thus would be dangerous if thoses data were on the stack. For what
> I understand, when a delegate can access the local data of a function,
> those data are set on the heap instead of the stack, resulting on a
> slower function call, but on a safe delegate behaviour.
>
> I'm wondering what's going on behind the hood when such a function is
> called. are the parameter passed to the function on the stack and the
> copied on the heap ? In such a situation, data are copied two times.
> Will a postblit constructor be called two times ? Or is the function
> taggued as « heap function » and then only the pointer is passed in the
> function call ?
It's the latter. A delegate is simply a function pointer/context pointer
pair, and the exact same thing is used for pointers to member functions
as for lexical closures.
> Secondly, how does thing like scope(exit) are handled in such a case ?
> When the constext is collected by the GC ? When the function ends it's
> execution ? The try {} finally {} analogy suggest the second one, but
> this is definitively not an exit of the scope, the scope being still
> accsible throw the delegate.
scope(exit) foo();
// stuff
is simply rewritten as
try {
// stuff
}
finally {
foo();
}
Hence, again the latter is the case. In this case:
string delegate() foo() {
string s = "initialized";
scope( exit ) s = "destroyed";
auto ret = (){return s;}
return ret;
}
void bar() {
assert(foo()() == "destroyed");
}
The assert passes.
> Those are exemple but more generaly, my question isn't about thoses
> exemples. It is about what really is going on. Let's say, what would be
> the C translation of such a function call or somethung similar.
void foo() {
int x = 5;
auto dg = () {x = 4;}
dg();
}
is roughly equivalent to:
typedef struct foo_dg_1_delegate {
void (*funcptr)(struct foo_dg_1_context*);
void* ptr;
};
typedef struct foo_dg_1_context {
int x;
};
void foo_dg_1(struct foo_dg_1_context* ctx) {
ctx->x = 4;
}
void foo(void) {
struct foo_dg_1_delegate dg;
struct foo_dg_1_context* ctx = (struct
foo_dg_1_context*)malloc(sizeof(struct foo_dg_1_context));
dg.funcptr = &foo_dg_1;
dg.ptr = ctx;
ctx->x = 5;
dg.funcptr(dg.ptr);
}
--
Simen
More information about the Digitalmars-d-learn
mailing list