On Friday, 2 June 2017 at 21:14:29 UTC, Seiji Emery wrote:
[...] 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?

Essentially, yes[1]. Though it's a D function pointer, not C.


Secondly, is it safe to typecast delegates for storage purposes – ie. cast `void delegate (ref Foo)` to `void delegate()`, or something similar?

It works for me, but if you're asking in terms of spec: I don't think it is specified. Though considering that you have to cast it back to the correct type I wouldn't call it safe.

The main worry that I have is that this could somehow wreak havoc with the GC-managed payload pointer, but I'm not sure.

AFAIK the GC won't collect any object that it considers live, so as long as you keep the context pointer somewhere the GC considers live, you are safe. See [2] on what the current implementation considers live.



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; [...]

Be sure that if you interact with operating system mechanisms such as epoll or kqueue to never have the OS C side point to memory that is not also pointed to from the D side or registered via GC.addRoot / GC.addRange, or you are likely going to end up with C pointers into collected memory.

Ah, and uh... one last thing. What's the worst that could happen from calling a `ref Foo` signature through a void* pointer?

Undefined behaviour.

[1] https://dlang.org/spec/abi.html#delegates
[2] https://dlang.org/phobos/core_memory.html#.GC

Reply via email to