November 11, 2019 Distinguishing a pointer to a function and a closure | ||||
---|---|---|---|---|
| ||||
While debugging phobos I came across some stuff I don't understand. A small example: void foo(void* p) { Object o = cast(Object) p; ClassInfo oc = typeid(o); } class Bar { void some_func(int i) {} void do_something(void delegate(int) d) { // is it possible to check here, if d.ptr can be passed to foo? foo(d.ptr); } } void main() { auto b = new Bar(); b.do_something(&b.some_func); // OK b.do_something(i => b.some_func(i)); // crashes } While the first call to do_something succeeds, the second one crashes. That's probably, because a closure is not an 'Object' and the cast in foo should never happen (a normal delegate seems to be an Object somehow, though). Is there any chance to notice this in "do_something" and emergency-exit there (e.g. with some assert call)? Background of the question: Issue 9603 [1] reports some crashes when using std.signals. I meanwhile found out, that the crash happens inside "_d_toObject", which is a function in the runtime [2]. The documentation tells, that this function crashes if the pointer does not point to a class, an interface or is the null pointer. It would be nice to avoid the crash by some check before the call to _d_toObject. [1] https://issues.dlang.org/show_bug.cgi?id=9603 [2] https://dlang.org/library/rt/cast_/_d_to_object.html |
November 11, 2019 Re: Distinguishing a pointer to a function and a closure | ||||
---|---|---|---|---|
| ||||
Posted in reply to berni44 | On Monday, 11 November 2019 at 13:10:44 UTC, berni44 wrote:
> (a normal delegate seems to be an Object somehow, though).
The .ptr method is a pointer to the data associated with the delegate. It might be an object (class or struct) or it might be a memory block (for local variables on the stack or a closure).
There is no way to tell the difference between these in D, even at runtime. The .ptr member drops all source information.
The code should probably be rewritten to avoid inspecting the .ptr member entirely. Maybe have it wrap the function internally - right at the point when it receives the delegate or write a whole new function that takes object and method separately - or something.
|
Copyright © 1999-2021 by the D Language Foundation