Re: Call a function with a function pointer

2013-10-13 Thread Benjamin Thaut

Am 10.10.2013 17:45, schrieb Namespace:

On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:

Namespace:


You mean like this?

void foo(T)(extern(C) void function(T*) func) {

}


That prints: Error: basic type expected, not extern


In theory that's correct, in practice the compiler refuses that, it's
in Bugzilla, so try to define the type outside the signature (untested):

alias TF = extern(C) void function(T*);

void foo(T)(TF func) {}

Bye,
bearophile


/d917/f732.d(8): Error: basic type expected, not extern
/d917/f732.d(8): Error: semicolon expected to close alias declaration
/d917/f732.d(8): Error: no identifier for declarator void function(T*)


I found a possible workaround. Its ugly as hell, but at least it works 
until the bugs are fixed. The trick is to make a helper struct. Define 
the function you want within that, and then use typeof to get the type.



import std.stdio;

extern(C) void testFunc(int* ptr)
{
*ptr = 5;
}

struct TypeHelper(T)
{
extern(C) static void func(T*);
alias typeof(func) func_t;
}

void Foo(T)(TypeHelper!T.func_t func, T* val)
{
func(val);
}

void main(string[] args)
{
pragma(msg, TypeHelper!int.func_t.stringof);
int test = 0;
Foo!int(testFunc, test);
writefln(%d, test);
}

--
Kind Regards
Benjamin Thaut


Re: Call a function with a function pointer

2013-10-13 Thread Artur Skawina
On 10/13/13 16:43, Benjamin Thaut wrote:
 Am 10.10.2013 17:45, schrieb Namespace:
 On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:
 Namespace:

 You mean like this?
 
 void foo(T)(extern(C) void function(T*) func) {

 }
 

 That prints: Error: basic type expected, not extern

 In theory that's correct, in practice the compiler refuses that, it's
 in Bugzilla, so try to define the type outside the signature (untested):

 alias TF = extern(C) void function(T*);

 void foo(T)(TF func) {}

 Bye,
 bearophile

 /d917/f732.d(8): Error: basic type expected, not extern
 /d917/f732.d(8): Error: semicolon expected to close alias declaration
 /d917/f732.d(8): Error: no identifier for declarator void function(T*)
 
 I found a possible workaround. Its ugly as hell, but at least it works until 
 the bugs are fixed. 

There's no need for such ugly workarounds -- this is just a problem with
the *new* alias syntax. The old one accepts it (unless this changed recently):

alias extern(C) static void function(int*) Func_t;

artur


Re: Call a function with a function pointer

2013-10-13 Thread Benjamin Thaut

Am 13.10.2013 17:17, schrieb Artur Skawina:

On 10/13/13 16:43, Benjamin Thaut wrote:

Am 10.10.2013 17:45, schrieb Namespace:

On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:

Namespace:


You mean like this?

void foo(T)(extern(C) void function(T*) func) {

}


That prints: Error: basic type expected, not extern


In theory that's correct, in practice the compiler refuses that, it's
in Bugzilla, so try to define the type outside the signature (untested):

alias TF = extern(C) void function(T*);

void foo(T)(TF func) {}

Bye,
bearophile


/d917/f732.d(8): Error: basic type expected, not extern
/d917/f732.d(8): Error: semicolon expected to close alias declaration
/d917/f732.d(8): Error: no identifier for declarator void function(T*)


I found a possible workaround. Its ugly as hell, but at least it works until 
the bugs are fixed.


There's no need for such ugly workarounds -- this is just a problem with
the *new* alias syntax. The old one accepts it (unless this changed recently):

 alias extern(C) static void function(int*) Func_t;

artur



Oh so this bug was fixed? Thats good to know.


Re: Call a function with a function pointer

2013-10-11 Thread Artur Skawina
On 10/10/13 20:54, Dicebot wrote:
 On Thursday, 10 October 2013 at 17:47:54 UTC, Namespace wrote:
 
 import std.stdio;

 void foo1(void function(void*) fp) { }
 void foo2(void function(int) fp) { }
 void foo3(void*) { }

 void main()
 {
 foo1((void* ptr) = ( assert(ptr is null) ));
 foo2((int a) = ( a + 1 )); /// Fails: Error: function foo2 (void 
 function(int) fp) is not callable using argument types (int function(int a) 
 pure nothrow @safe)
 
 foo1(foo3);
 
 void foo4(void function(void*) fp) { }
 foo1(foo4); /// Fails: Error: function foo1 (void function(void*) fp) 
 is not callable using argument types (void delegate(void function(void*) fp))
 }
 
 
 You are using short lambda syntax a = b. Here `b` is always return 
 statement. It is equivalent to (a) { return b; }. And your `foo2` signature 
 expects lambda returning void, like (a) { return; }
 
 Second error is DMD incompetence in deducing minimal required type of nested 
 function. It always treats them as delegates (== having hidden context 
 pointer) even if those do not refer any actual context. And plain lambdas are 
 of course binary incompatible with delegates (closures) because of that extra 
 pointer field.

It's probably not just incompetence (the compiler is able to figure this
out in other contexts), but a deliberate choice. Having function types
depend on their bodies would not be a good idea. Eg

int c;
auto f() {
   int a = 42;
   int f1() { return a; }
   int f2() { return 0; }
   return !c?f1:f2;
}

Mark f2 as 'static' and this code will no longer compile. If that would
be done automatically then you'd have to 'undo' it manually, which would
cause even more problems (consider generic code, which isn't prepared
to handle this).

artur

[1] at least without other language improvements; enabling overloading on
'static', plus a few other enhancements, would change the picture.


Re: Call a function with a function pointer

2013-10-11 Thread Dicebot

On Friday, 11 October 2013 at 15:55:17 UTC, Artur Skawina wrote:
It's probably not just incompetence (the compiler is able to 
figure this
out in other contexts), but a deliberate choice. Having 
function types

depend on their bodies would not be a good idea. Eg

int c;
auto f() {
   int a = 42;
   int f1() { return a; }
   int f2() { return 0; }
   return !c?f1:f2;
}

Mark f2 as 'static' and this code will no longer compile. If 
that would
be done automatically then you'd have to 'undo' it manually, 
which would
cause even more problems (consider generic code, which isn't 
prepared

to handle this).

artur

[1] at least without other language improvements; enabling 
overloading on
'static', plus a few other enhancements, would change the 
picture.


Agreed.

However, I do feel uncomfortable with new habit to put `static` 
everywhere to avoid hidden compiler help :(


Re: Call a function with a function pointer

2013-10-10 Thread Dicebot

On Thursday, 10 October 2013 at 14:13:47 UTC, Namespace wrote:

I have this function:

void foo(T)(void function(T*) test) { }


And want to call it with a C function:

foo!(SDL_Surface)(SDL_FreeSurface);


but I get:
Fehler	1	Error: foo (void function(SDL_Surface*) test) is not 
callable using argument types (extern (C) void 
function(SDL_Surface*) nothrow)


What would be the smartest solution?


Wrap it in a lambda. Or change foo() signature to accept 
`extern(C)` functions - you can't just mix calling convention.


Re: Call a function with a function pointer

2013-10-10 Thread Benjamin Thaut

Am 10.10.2013 16:13, schrieb Namespace:

I have this function:

void foo(T)(void function(T*) test) { }


And want to call it with a C function:

foo!(SDL_Surface)(SDL_FreeSurface);


but I get:
Fehler1Error: foo (void function(SDL_Surface*) test) is not
callable using argument types (extern (C) void function(SDL_Surface*)
nothrow)

What would be the smartest solution?


If you can change the signature of foo just add a extern(c) to the 
function pointer declaration.


Otherwise just wrap the SDL_FreeSurface call into a delegate on the 
caller side.


--
Kind Regards
Benjamin Thaut


Re: Call a function with a function pointer

2013-10-10 Thread Dicebot

On Thursday, 10 October 2013 at 14:40:09 UTC, Namespace wrote:

Example? I do not use lambdas often.


void foo(T)(void function(T*) test)
{
}

extern(C) void bar(int*) { }

void main()
{
foo( (int* a) = bar(a) );
}

I don't know to what extent IFTI can work here though.


Re: Call a function with a function pointer

2013-10-10 Thread Namespace

On Thursday, 10 October 2013 at 14:28:20 UTC, Dicebot wrote:

On Thursday, 10 October 2013 at 14:13:47 UTC, Namespace wrote:

I have this function:

void foo(T)(void function(T*) test) { }


And want to call it with a C function:

foo!(SDL_Surface)(SDL_FreeSurface);


but I get:
Fehler	1	Error: foo (void function(SDL_Surface*) test) is not 
callable using argument types (extern (C) void 
function(SDL_Surface*) nothrow)


What would be the smartest solution?


Wrap it in a lambda.


Example? I do not use lambdas often.


Re: Call a function with a function pointer

2013-10-10 Thread Namespace

On Thursday, 10 October 2013 at 14:44:00 UTC, Dicebot wrote:

On Thursday, 10 October 2013 at 14:40:09 UTC, Namespace wrote:

Example? I do not use lambdas often.


void foo(T)(void function(T*) test)
{
}

extern(C) void bar(int*) { }

void main()
{
foo( (int* a) = bar(a) );
}

I don't know to what extent IFTI can work here though.


That works. Thanks.


Re: Call a function with a function pointer

2013-10-10 Thread Namespace

On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:

Namespace:


You mean like this?

void foo(T)(extern(C) void function(T*) func) {

}


That prints: Error: basic type expected, not extern 


In theory that's correct, in practice the compiler refuses 
that, it's in Bugzilla, so try to define the type outside the 
signature (untested):


alias TF = extern(C) void function(T*);

void foo(T)(TF func) {}

Bye,
bearophile


/d917/f732.d(8): Error: basic type expected, not extern
/d917/f732.d(8): Error: semicolon expected to close alias 
declaration
/d917/f732.d(8): Error: no identifier for declarator void 
function(T*)


Re: Call a function with a function pointer

2013-10-10 Thread bearophile

Namespace:


/d917/f732.d(8): Error: basic type expected, not extern
/d917/f732.d(8): Error: semicolon expected to close alias 
declaration
/d917/f732.d(8): Error: no identifier for declarator void 
function(T*)


It seems that even the new alias syntax doesn't support the 
extern :-) Perhaps this bug is not yet in Bugzilla.


Try:

alias extern(C) void function(T*) TF;
void foo(T)(TF func) {}

Bye,
bearophile


Re: Call a function with a function pointer

2013-10-10 Thread Dicebot

On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:

Namespace:


You mean like this?

void foo(T)(extern(C) void function(T*) func) {

}


That prints: Error: basic type expected, not extern 


In theory that's correct, in practice the compiler refuses 
that, it's in Bugzilla, so try to define the type outside the 
signature (untested):


alias TF = extern(C) void function(T*);

void foo(T)(TF func) {}

Bye,
bearophile


That is limitation of current extern - it can only be attached to 
symbol declarations, not types. AFAIK you need to do `extern(C) 
alias TF = ...` but anyway this method is very likely to break 
IFTI completely.




Re: Call a function with a function pointer

2013-10-10 Thread Namespace


import std.stdio;

void foo1(void function(void*) fp) { }
void foo2(void function(int) fp) { }
void foo3(void*) { }

void main()
{
foo1((void* ptr) = ( assert(ptr is null) ));
	foo2((int a) = ( a + 1 )); /// Fails: Error: function foo2 
(void function(int) fp) is not callable using argument types (int 
function(int a) pure nothrow @safe)


foo1(foo3);

void foo4(void function(void*) fp) { }
	foo1(foo4); /// Fails: Error: function foo1 (void 
function(void*) fp) is not callable using argument types (void 
delegate(void function(void*) fp))

}

Can someone explain that to me?


Re: Call a function with a function pointer

2013-10-10 Thread Dicebot

On Thursday, 10 October 2013 at 17:47:54 UTC, Namespace wrote:


import std.stdio;

void foo1(void function(void*) fp) { }
void foo2(void function(int) fp) { }
void foo3(void*) { }

void main()
{
foo1((void* ptr) = ( assert(ptr is null) ));
	foo2((int a) = ( a + 1 )); /// Fails: Error: function foo2 
(void function(int) fp) is not callable using argument types 
(int function(int a) pure nothrow @safe)


foo1(foo3);

void foo4(void function(void*) fp) { }
	foo1(foo4); /// Fails: Error: function foo1 (void 
function(void*) fp) is not callable using argument types (void 
delegate(void function(void*) fp))

}

Can someone explain that to me?


You are using short lambda syntax a = b. Here `b` is always 
return statement. It is equivalent to (a) { return b; }. And 
your `foo2` signature expects lambda returning void, like (a) { 
return; }


Second error is DMD incompetence in deducing minimal required 
type of nested function. It always treats them as delegates (== 
having hidden context pointer) even if those do not refer any 
actual context. And plain lambdas are of course binary 
incompatible with delegates (closures) because of that extra 
pointer field.


Re: Call a function with a function pointer

2013-10-10 Thread Andrej Mitrovic
On 10/10/13, bearophile bearophileh...@lycos.com wrote:
 Perhaps this bug is not yet in Bugzilla.

I'm pretty sure I saw it filed somewhere. Can't find it though..


Re: Call a function with a function pointer

2013-10-10 Thread bearophile

Andrej Mitrovic:


I'm pretty sure I saw it filed somewhere. Can't find it though..


I have just added the new test case :-)
http://d.puremagic.com/issues/show_bug.cgi?id=6754

Bye,
bearophile