www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - scope + delegates = irritating

reply Hendrik Renken <funsheep gmx.net> writes:
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
}
Apr 10 2007
parent BCS <ao pathlink.com> writes:
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.
Apr 10 2007