digitalmars.D.learn - How does calling function pointers work?
- helxi (28/28) Nov 12 2018 As far as I understand, calling a function pointer with an
- helxi (2/4) Nov 12 2018 Correction, it was meant to print 12304. My bad.
- Rene Zwanenburg (4/7) Nov 12 2018 Idk where you got that syntax from, but there's no syntactic
- helxi (18/21) Nov 12 2018 import std.stdio;
- Alex (5/26) Nov 12 2018 Yes, seems so. Accordingly to
- Mike Parker (19/21) Nov 12 2018 spawn is a template that takes a function pointer and a variable
- Rene Zwanenburg (11/32) Nov 12 2018 That's right. spawn() is a function in the standard library that
As far as I understand, calling a function pointer with an argument in D looks like: call(&fnptr, argTofn0, argTofn1, argTofn3); This immediately struck me a very weak syntax to me so I decided to explore my concerns. I made a function pointer that takes an indefinite number of arguments. 1 import std.stdio; 2 3 int total(int[] numbers ...) { 4 int result; 5 for(ulong i = 0; i < numbers.length; result += numbers[i++]){} 6 return result; 7 } 8 9 10 void main() { 11 writeln(total(1000, 200, 30, 4)); // 1234 12 writeln(&total, 1000, 200, 30, 4); // 55CA386877AC1000200304 13 writeln((&total, 1000, 200, 30), 4); // error lmao 14 } How do you guys make writeln distinguish between an arg meant for writeln from an arg meant for &total? FYI Line 12 was meant to print 1234. Line 13 was meant to print 1234 too, but for a different reason.
Nov 12 2018
On Monday, 12 November 2018 at 16:08:28 UTC, helxi wrote:Line 12 was meant to print 1234. Line 13 was meant to print 1234 too, but for a different reason.Correction, it was meant to print 12304. My bad.
Nov 12 2018
On Monday, 12 November 2018 at 16:08:28 UTC, helxi wrote:As far as I understand, calling a function pointer with an argument in D looks like: call(&fnptr, argTofn0, argTofn1, argTofn3);Idk where you got that syntax from, but there's no syntactic difference between calling normal functions and function pointers: https://run.dlang.io/is/I6u0rg
Nov 12 2018
On Monday, 12 November 2018 at 16:25:13 UTC, Rene Zwanenburg wrote:Idk where you got that syntax from, but there's no syntactic difference between calling normal functions and function pointers:import std.stdio; import std.concurrency; import core.thread; void worker(int firstNumber) { foreach (i; 0 .. 4) { Thread.sleep(500.msecs); writeln(firstNumber + i); } } void main() { foreach (i; 1 .. 3) { spawn(&worker, i * 10); } } Looks like worker needs an int and spawn(&worker, i * 10) seems to feed it's second arg to worker(?)
Nov 12 2018
On Monday, 12 November 2018 at 16:29:24 UTC, helxi wrote:On Monday, 12 November 2018 at 16:25:13 UTC, Rene Zwanenburg wrote:Yes, seems so. Accordingly to https://dlang.org/library/std/concurrency/spawn.html However, there are more restrictions on input params in the notes section.Idk where you got that syntax from, but there's no syntactic difference between calling normal functions and function pointers:import std.stdio; import std.concurrency; import core.thread; void worker(int firstNumber) { foreach (i; 0 .. 4) { Thread.sleep(500.msecs); writeln(firstNumber + i); } } void main() { foreach (i; 1 .. 3) { spawn(&worker, i * 10); } } Looks like worker needs an int and spawn(&worker, i * 10) seems to feed it's second arg to worker(?)
Nov 12 2018
On Monday, 12 November 2018 at 16:29:24 UTC, helxi wrote:Looks like worker needs an int and spawn(&worker, i * 10) seems to feed it's second arg to worker(?)spawn is a template that takes a function pointer and a variable number of parameters. Both the pointer and the parameters are passed on to an internal _spawn function. https://github.com/dlang/phobos/blob/master/std/concurrency.d#L446 _spawn is has the same template parameters as spawn. It has an internal function that actually makes the call to the function pointer (fn): void exec() { thisInfo.ident = spawnTid; thisInfo.owner = ownerTid; fn(args); } https://github.com/dlang/phobos/blob/master/std/concurrency.d#L538 A few lines down from there, a pointer to exec is passed to either scheduler.spawn or the Thread constructor. When it's ultimately called, your function will be called in turn. At any rate, the actual call to the function pointer is fn(args).
Nov 12 2018
On Monday, 12 November 2018 at 16:29:24 UTC, helxi wrote:On Monday, 12 November 2018 at 16:25:13 UTC, Rene Zwanenburg wrote:That's right. spawn() is a function in the standard library that takes a function pointer, and all the arguments to pass to that function. It's a bit unusual in that regard: normally when using function pointers the arguments are provided by the code that receives the function pointer. Internally, spawn will call the function pointer just like I did in my example, but on another thread. Here's an example where a function pointer is passed around with the arguments provided by the callee: https://run.dlang.io/is/ArCN5tIdk where you got that syntax from, but there's no syntactic difference between calling normal functions and function pointers:import std.stdio; import std.concurrency; import core.thread; void worker(int firstNumber) { foreach (i; 0 .. 4) { Thread.sleep(500.msecs); writeln(firstNumber + i); } } void main() { foreach (i; 1 .. 3) { spawn(&worker, i * 10); } } Looks like worker needs an int and spawn(&worker, i * 10) seems to feed it's second arg to worker(?)
Nov 12 2018