Thread overview
should a delegate context ever be a non pointer?
May 04, 2007
BCS
May 05, 2007
Walter Bright
May 05, 2007
BCS
May 04, 2007
A while ago I was writing some code and ended up with a template something like this:

struct S
{
	int i;
	// other stuff
}

S FillS(int j, int k)(MyObject o)
{
	S ret;
	o.something(k);
	ret.i = j;
	// fill other stuff

	return ret;
}

I was building large tables of function pointers from this template. All was well and good when I only had one version of it actual used. Then I actually used it with the 40+ versions that actually exist. It made my code run about 100% longer (I'm calling these things a lot).

So then I looked around for a better way to do it and realized that there  was less than 32 bits of difference between the versions (i and k were small) so I switch to this:

union U
{
	S2* pt
	struct
	{
		ushort h;
		ushort l;
	}
}

struct S2
{
	S FillS(MyObject o)
	{
		U u;
		S ret;

		u.pt = this;
		o.something(u.h);
		ret.i = u.l;
		// fill other stuff

		return ret;
	}

	static delegate(MyObject) Build(uint i, uint k)
	{
		U u;
		u.h = k;
		u.l = i;
		return &u.pt.FillS;
	}
}

Most of the performance came back. However, That is just some funky programming.

My question is, is there any reason that such a things shouldn't be endorsed? What that would requirer is that the context in a delegate be defined to be an opaque field and allowed to be anything that fits in a size_t. Then the above would become:



struct Ctx
{
	ushort h;
	ushort l;
}


S FillS(Ctx c, MyObject o)
{
	S ret;
	o.something(c.h);
	ret.i = c.l;

	// fill other stuff
	return ret;
}

static delegate(MyObject) Build(uint i, uint k)
{
	Ctx c;
	c.h = k;
	c.l = i;
	return &c.FillS;
}
May 05, 2007
BCS wrote:
> static delegate(MyObject) Build(uint i, uint k)
> {
>     Ctx c;
>     c.h = k;
>     c.l = i;
>     return &c.FillS;
> }

Looks like you're returning the address of a stack variable, which will cause erratic behavior.
May 05, 2007
Reply to Walter,

> BCS wrote:
> 
>> static delegate(MyObject) Build(uint i, uint k)
>> {
>> Ctx c;
>> c.h = k;
>> c.l = i;
>> return &c.FillS;
>> }
> Looks like you're returning the address of a stack variable, which
> will cause erratic behavior.
> 

The distinction that the proposed syntax would use is that the function that is used has, as it's first argument, a structure as opposed to a pointer to a structure. This would result in the structure being loaded (by value) into the context of the delegate and alls well and good. Of course the exact syntax is not important, What I'm hoping for is some non-hack way to use the context of a delegate for something other than a pointer to a struct, object or stack frame.