April 10, 2007
I am having some problems with delegates in classes or structs.

i would like to write a simple SDL KeyMapper. It should store delegates in a associative array, so i know what to invoke on which key, pressed on the keyboard.

for mainscope foo and modulescope foo (see below) it works perfect, but for the foo delegate defined within the struct, with dmd 1.010 i get a segmentationfault on the line "keymap[3]()".

what do i have to do, to invoke the foo, defined in the struct?

thanks in advance
hendrik


module KeyManager;

import std.stdio;
import std.string;

private void delegate()[int] keymap;


public void setKey(int key, void delegate() dg)
{
	keymap[key] = dg;
}

public bool isSetKey(int key)
{
	return keymap[key] != null;
}


void moduleScopeTest()
{
	void foo()
	{
		writefln("modulescope was invoked ");
	}
	setKey(2, &foo);
}

struct scopeTestStruct
{
	void foo()
	{
		writefln("structscope was invoked");
	}

}

void main()
{
	scopeTest();

	void foo()
	{
		writefln("mainscope was invoked ");
	}
	setKey(1, &foo);

	scopeTestStruct c;
	setKey(3, &c.foo);

	if (isSetKey(1)) writefln("1 is set");
	if (isSetKey(3)) writefln("3 is set");

	keymap[1](); //mainscope   foo
	keymap[2](); //modulescope foo
	keymap[3](); //structscope foo
}
April 10, 2007
Reply to Hendrik,

> I am having some problems with delegates in classes or structs.
> 
> i would like to write a simple SDL KeyMapper. It should store
> delegates in a associative array, so i know what to invoke on which
> key, pressed on the keyboard.
> 
> for mainscope foo and modulescope foo (see below) it works perfect,
> but for the foo delegate defined within the struct, with dmd 1.010 i
> get a segmentationfault on the line "keymap[3]()".
> 
> what do i have to do, to invoke the foo, defined in the struct?
> 
[...]
> void main()
> {
> scopeTest();
> void foo()
> {
> writefln("mainscope was invoked ");
> }
> setKey(1, &foo);
> scopeTestStruct c;
> setKey(3, &c.foo);
> if (isSetKey(1)) writefln("1 is set");
> if (isSetKey(3)) writefln("3 is set");
> keymap[1](); //mainscope   foo
> keymap[2](); //modulescope foo
> keymap[3](); //structscope foo
> }

keymap[1]() is just fine.

keymap[2]() should not work because a delegate from a nested non-static function is invalid after the enclosing function call returns. This is because the context on the delegate is the stack frame of the enclosing function call. It seems to work in this case because it doesn't reference anything in the enclosing scope.

IIRC, in delegates !=null only check the fn-ptr or the context, not both. But still it should be working.

One thought, the call to [2] might by messing with some stack space. Try it without that call.