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









Steven Schveighoffer <schveiguy yahoo.com> 