Initializing a table of delegates with no-op stubs

Steven Schveighoffer schveiguy at gmail.com
Thu Jan 9 23:11:37 UTC 2020


On 1/9/20 5:02 PM, H. S. Teoh wrote:
> I have a struct containing a bunch of delegates:
> 
> 	struct S {
> 		void delegate(int blah) dg1;
> 		void delegate(string blah) dg2;
> 		void delegate(int x, int y) dg3;
> 		... // lots of these
> 	}
> 
> How do I initialize them to no-op stubs?  I've tried all sorts of ways
> but couldn't get it to work.  It's easy to do with a *function pointer*
> -- just declare a dummy no-op function with the right signature and take
> its address:
> 
> 	void dummy(int) {}
> 	struct S {
> 		void function(int) f1 = &dummy; // OK
> 
> 		// But it doesn't work with delegates, no way, no how:
> 		void delegate(int) dg1 = &dummy; // NG
> 		void delegate(int) dg2 = (int) {}; // NG
> 		void delegate(int) dg3 = (int) => dummy(0); // NG
> 	}

I thought this might work, but toDelegate seems to not be usable at 
compile time:

void delegate(int) dg1 = toDelegate((int) {});

> 
> I even tried to make a function that returns an empty delegate, but when
> I try to assign that to the struct member the compiler complains that
> it's a non-constant expression.
> 
> Seriously, why is it so hard to initialize a delegate field to point to
> a 'ret' instruction?!  That's all I need.  It doesn't even need a
> context pointer, since it's supposed to do nothing.  Since it's possible
> to initialize struct fields to function pointers, surely it can't be
> *that* hard to also initialize them to point to empty delegates?
> 
> The only success I have is to defer to runtime, and even then it
> involves a whole mouthful of periphrasis:
> 
> 	S s;
> 	foreach (ref dg; s.tupleof)
> 	{
> 		import std.traits : Parameters;
> 		void impl(size_t i)(Parameters!(typeof(dg))) {}
> 		dg = &impl;
> 	}
> 
> Am I missing something obvious??

toDelegate should work at runtime, but you'd have to know the types 
anyway, so your runtime thing is probably just as verbose using that. 
I'd recommend still using static void impl, and using toDelegate to 
avoid any closures.

It would be useful if toDelegate either worked at compile time, or the 
compiler allowed auto conversion to delegates (as it's always possible, 
a la toDelegate).

-Steve


More information about the Digitalmars-d mailing list