Hi, bit of a long-time lurker here.

I had a few questions about D delegates: first, D delegates are the size of two pointers (16 bytes) on my machine, so I'd assume that they're implemented as a pair of pointers; presumably a C function pointer, and a GC-managed payload / context / this pointer – is this correct?

Secondly, is it safe to typecast delegates for storage purposes – ie. cast `void delegate (ref Foo)` to `void delegate()`, or something similar? Since delegates seem to just be a pair of pointers, it seems like this should work; it's perfectly safe to cast C function pointers, for instance, provided that they're cast back to the correct type before actually being called. The main worry that I have is that this could somehow wreak havoc with the GC-managed payload pointer, but I'm not sure. It seems like this shouldn't be a problem since payloads change between delegates anyways (reference to object vs reference to function scope), and delegates with different signatures could point to the same object / scope – ie. the payload type and pointed-to function signature have nothing to do with each other, and GC references to and within the payload should still work properly even if I cast a delegate with N arguments to one with zero. But I'm just guessing here.


For context, I'm working on an event system for a small hobby project, and it would be extremely useful if I could store delegates with different type signatures in the same storage container; these delegates will always be converted back to the correct type signature before being called (probably by storing typeinfo of the first / only event argument and comparing that), so that's a non-issue. Using a different approach than putting listeners that can listen to any kind of event everywhere might be better and more efficient architecturally, but would be much less flexible / powerful I think. And yes, I've looked into std.variadic; I just want something slightly lower-level with more control over how I actually dispatch and filter events.


Ah, and uh... one last thing. What's the worst that could happen from calling a `ref Foo` signature through a void* pointer? Once again, using delegate / function pointer casting shenanigans. Foo is a struct. The memory layout seems to be the same, so this technically works.

Thanks!

Reply via email to