www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Delegate / Error: cannot implicitly convert expression...

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
Why does the follwing code give: Error: cannot implicitly convert 
expression & myFunc of type void function(int a) to void delegate(int)


void myFunc(int a){return;}

void main()
{
    void delegate(int) dg;
    dg = &myFunc;
}

See: https://run.dlang.io/is/iTYo2L

-- 
Robert M. Mnch
http://www.saphirion.com
smarter | better | faster
Jun 15 2019
parent reply Anonymouse <zorael gmail.com> writes:
On Saturday, 15 June 2019 at 15:54:00 UTC, Robert M. Münch wrote:
 Why does the follwing code give: Error: cannot implicitly 
 convert expression & myFunc of type void function(int a) to 
 void delegate(int)


 void myFunc(int a){return;}

 void main()
 {
    void delegate(int) dg;
    dg = &myFunc;
 }

 See: https://run.dlang.io/is/iTYo2L
By design, I think. "delegate and function objects cannot be mixed. But the standard function std.functional.toDelegate converts a function to a delegate." Your example compiles if the assignment is changed to dg = toDelegate(&myFunc); (given appropriate imports). https://tour.dlang.org/tour/en/basics/delegates https://dlang.org/phobos/std_functional.html#.toDelegate
Jun 15 2019
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2019-06-15 16:19:23 +0000, Anonymouse said:

 By design, I think: "delegate and function objects cannot be mixed. But 
 the standard function std.functional.toDelegate converts a function to 
 a delegate."
 
 Your example compiles if the assignment is changed to dg = 
 toDelegate(&myFunc); (given appropriate imports).
 
 https://tour.dlang.org/tour/en/basics/delegates
 
 https://dlang.org/phobos/std_functional.html#.toDelegate
Hmm... but this here compiles: void main() { import std.stdio: write, writeln, writef, writefln; void foo(int a) {return; } void test() { void delegate(int) dg; dg = &foo; } } See: https://run.dlang.io/is/U7uhAX Is it because inside main() there is a stack frame? And with a global function there is none? I'm a bit confused... -- Robert M. Mnch http://www.saphirion.com smarter | better | faster
Jun 15 2019
next sibling parent Alex <sascha.orlov gmail.com> writes:
On Saturday, 15 June 2019 at 16:34:22 UTC, Robert M. Münch wrote:
 On 2019-06-15 16:19:23 +0000, Anonymouse said:

 By design, I think: "delegate and function objects cannot be 
 mixed. But the standard function std.functional.toDelegate 
 converts a function to a delegate."
 
 Your example compiles if the assignment is changed to dg = 
 toDelegate(&myFunc); (given appropriate imports).
 
 https://tour.dlang.org/tour/en/basics/delegates
 
 https://dlang.org/phobos/std_functional.html#.toDelegate
Hmm... but this here compiles: void main() { import std.stdio: write, writeln, writef, writefln; void foo(int a) {return; } void test() { void delegate(int) dg; dg = &foo; } } See: https://run.dlang.io/is/U7uhAX Is it because inside main() there is a stack frame? And with a global function there is none? I'm a bit confused...
Correct. Inside main, foo is a delegate. https://dlang.org/spec/function.html#nested
Jun 15 2019
prev sibling parent reply user1234 <user1234 12.de> writes:
On Saturday, 15 June 2019 at 16:34:22 UTC, Robert M. Münch wrote:
 On 2019-06-15 16:19:23 +0000, Anonymouse said:

 By design, I think: "delegate and function objects cannot be 
 mixed. But the standard function std.functional.toDelegate 
 converts a function to a delegate."
 
 Your example compiles if the assignment is changed to dg = 
 toDelegate(&myFunc); (given appropriate imports).
 
 https://tour.dlang.org/tour/en/basics/delegates
 
 https://dlang.org/phobos/std_functional.html#.toDelegate
Hmm... but this here compiles: void main() { import std.stdio: write, writeln, writef, writefln; void foo(int a) {return; } void test() { void delegate(int) dg; dg = &foo; } } See: https://run.dlang.io/is/U7uhAX Is it because inside main() there is a stack frame? And with a global function there is none? I'm a bit confused...
yes. delegate is a function pointer + its context. At the global scope there's no context. Actually the following works fine: --- void foo(){writeln(__PRETTY_FUNCTION__);} void main(string[] args) { void delegate() dg; dg.funcptr = &foo; dg.ptr = null; // usually a "this" or a frame address dg(); } --- because dg.ptr would be used to retrieve the offset of the locals variable used in the parent stack or the address of a class instance (the this). But this is not required at all here. The opposite way would lead to various access violation.
Jun 15 2019
parent reply ag0aep6g <anonymous example.com> writes:
On Saturday, 15 June 2019 at 17:24:45 UTC, user1234 wrote:
 ---
 void foo(){writeln(__PRETTY_FUNCTION__);}

 void main(string[] args)
 {
     void delegate() dg;
     dg.funcptr = &foo;
     dg.ptr = null; // usually a "this" or a frame address
     dg();
 }
 ---

 because dg.ptr would be used to retrieve the offset of the 
 locals variable used in the parent stack or the address of a 
 class instance (the this). But this is not required at all 
 here. The opposite way would lead to various access violation.
That only works because foo doesn't have any parameters. When you add even just one, things will go wrong.
Jun 15 2019
parent user1234 <user1234 12.de> writes:
On Saturday, 15 June 2019 at 17:42:04 UTC, ag0aep6g wrote:
 On Saturday, 15 June 2019 at 17:24:45 UTC, user1234 wrote:
 ---
 void foo(){writeln(__PRETTY_FUNCTION__);}

 void main(string[] args)
 {
     void delegate() dg;
     dg.funcptr = &foo;
     dg.ptr = null; // usually a "this" or a frame address
     dg();
 }
 ---

 because dg.ptr would be used to retrieve the offset of the 
 locals variable used in the parent stack or the address of a 
 class instance (the this). But this is not required at all 
 here. The opposite way would lead to various access violation.
That only works because foo doesn't have any parameters. When you add even just one, things will go wrong.
True if was forgetting that the context is a hidden parameter... Maybe it depends on the calling convention too ?
Jun 15 2019