digitalmars.D.learn - delegates/lambas do not pick up calling convention
- Johnson Jones (33/33) Aug 09 2017 given somethign like Threads.threadsAddIdle
- Steven Schveighoffer (11/18) Aug 09 2017 Because D tries to avoid situations where the type depends on the usage....
- ag0aep6g (14/25) Aug 10 2017 1) You probably meant to apply `DD` to `x`.
- Timon Gehr (6/13) Aug 10 2017 I think this is a compiler bug. Try:
- Adam D. Ruppe (9/10) Aug 10 2017 You should very rarely use extern(C) delegate... delegate is a D
- Timon Gehr (20/30) Aug 10 2017 gdk is actually using a function with arguments of type (extern(C) int
given somethign like Threads.threadsAddIdle which takes an extern(C) int (void*) we can't seem to do threadsAddIdle((void*) { }, null); nor because D complains is not the correct type nor can we do delegate(void*) or extern(C) delegate(void*) {} and have to resort to verbosity to get it to work. Is there a way around that? Why can't D realize that an inline lambda should use the same calling convention? There is no harm in doing so. Maybe I'm doing it wrong: I've tried import gdk.Threads; alias DD = static extern(C) int delegate(void*); auto x = (void*) { return 1; }; gdk.Threads.threadsAddIdle(x, null); which gives the error (extern (C) int function(void* userData) funct, void* data) is not callable using argument types int function(void* _param_0) pure nothrow nogc safe, typeof(null)) While one can do something like gdk.Threads.threadsAddIdle(cast(GSourceFunc)(void* data) { return 1; }, null); which seems to work but the cast seems superfluous as D should be able to implicitly figure that out since it's an inline delegate.
Aug 09 2017
On 8/9/17 7:52 PM, Johnson Jones wrote:given somethign like Threads.threadsAddIdle which takes an extern(C) int (void*) we can't seem to do threadsAddIdle((void*) { }, null);Because D tries to avoid situations where the type depends on the usage. The implied type is based solely on the expression (in most cases, there are a few cases where it is affected by usage). FYI I also code in swift, and I run into situations all the time where the compiler can't figure out types for a statement because it hits some weird corner case that causes too much recursion in the compiler. In those cases, the compiler says "please split up your statement into multiple lines". So I'm kind of glad D doesn't go this route, as nice as it is conceptually. -Steve
Aug 09 2017
On 08/10/2017 01:52 AM, Johnson Jones wrote:I've tried import gdk.Threads; alias DD = static extern(C) int delegate(void*); auto x = (void*) { return 1; }; gdk.Threads.threadsAddIdle(x, null);1) You probably meant to apply `DD` to `x`. 2) `x` must be a `function`, not a `delegate`. 3) (optional) `static` is not needed. So: ---- import gdk.Threads; alias DD = extern(C) int function(void*); DD x = (void*) { return 1; }; gdk.Threads.threadsAddIdle(x, null); ----
Aug 10 2017
On 10.08.2017 01:52, Johnson Jones wrote:given somethign like Threads.threadsAddIdle which takes an extern(C) int (void*) we can't seem to do threadsAddIdle((void*) { }, null);I think this is a compiler bug. Try: threadsAddIdle((x){ }, null); It seems that the calling convention is deduced only if the parameter type needs to be deduced too. https://issues.dlang.org/show_bug.cgi?id=17739
Aug 10 2017
On Wednesday, 9 August 2017 at 23:52:00 UTC, Johnson Jones wrote:extern(C) delegate(void*) {}You should very rarely use extern(C) delegate... delegate is a D type, so the C function is almost certainly not actually receiving it. Only time you'd want an extern(C) using D types like delegates, arrays, strings, etc., is if the receiver is actually also written in D. idk if this would fix your problem, but it should be changed regardless.
Aug 10 2017
On 10.08.2017 15:22, Adam D. Ruppe wrote:On Wednesday, 9 August 2017 at 23:52:00 UTC, Johnson Jones wrote:gdk is actually using a function with arguments of type (extern(C) int function(void*),void*). Anyway, I think there are use cases for extern(C) delegates too, along the following lines: alias D=extern(C) int delegate(int); struct F(S,T...){ // this struct is compatible with C void* ptr; extern(C) S function(void*,T) funptr; auto opCall(T args){ return funptr(ptr,args); } } void main(){ int y=2; D dg=(x)=>x+y; auto f=*cast(F!(int,int)*)&dg; import std.stdio; writeln(f(3)); }extern(C) delegate(void*) {}You should very rarely use extern(C) delegate... delegate is a D type, so the C function is almost certainly not actually receiving it. Only time you'd want an extern(C) using D types like delegates, arrays, strings, etc., is if the receiver is actually also written in D. idk if this would fix your problem, but it should be changed regardless.
Aug 10 2017