MCL MCL - 3 months ago 16
C Question

How can I make a function that returns a function?

Big picture: I have a module with functions and a module with procedures and functions over those functions.

When I combine two functions (from function's module interface):

double f1(double alpha, double x);
double f2(double beta, double x);


In several ways, (one of them is adding):

double OP_Addition(double (*f)(double,double) , double (*g)(double,double), double param1, double param2, double x);


Gives no problem with the following (piece of) implementation:

z1 = (*f)(param1, x);
z2 = (*g)(param2, x);
y = z1 + z2;
return y;


But when I want to return a pointer to a "new" function, something like:

void *OP_PAdd( double (*f)(double,double), double param3 );


I can not get it to work properly, neither make the right "call". I want to have use the output "function" as input in other functions.

Answer

Other answers are correct and interesting, but you should be aware that in portable C99, there is no way to have genuine closures as C functions (and this is a fundamental limitation of C). If you are not aware of what closures are, read carefully the wikipage on them (and read also SICP, notably its §1.3). Notice however that in C++11 you do have closures, using std::function and lambda-expressions. And most other programming languages (Ocaml, Haskell, Javascript, Lisp, Clojure, Python, ....) have closures.

Because of the lack of genuine closures in C ("mathematically" the only closed values in C functions are global or static variables or literals), most libraries accepting C function pointers provide an API handling callbacks with some client data (a simple example could be qsort_r, but more seriously look inside GTK). That client data (generally an opaque pointer) can be used to keep closed values. You probably want to follow a similar convention (so systematically pass function pointer as callbacks with some additional client data), so you'll need to change the signatures of your C functions (instead of passing just a raw function pointer, you'll pass both a function pointer and some client data as a callback, to "emulate" closures).

You could sometimes generate a C function at runtime (using non-standard features, probably with the help of the operating system or of some external library). You might use some JIT compiling library such as GNU lightning, libjit (both would generate quickly some slow-running code), asmjit (you'll generate each machine instruction explicitly, and it is your responsability to emit fast x86-64 code), GCCJIT or LLVM (both are above existing compilers so can be used to emit -a bit slowly- some optimized code). On POSIX & Linux systems, you could also emit some C code in some temporary file /tmp/tempcode.c, fork a compilation (e.g. gcc -fPIC -Wall -O2 -shared /tmp/tempcode.c -o /tmp/tempcode.so) of that code into a plugin, and dynamically load that generated plugin using dlopen(3) & dlsym(3)..

BTW we don't know what is the actual application you are coding, but you might consider embedding inside it some interpreter, e.g. Lua or Guile. You'll then use and/or provide callbacks to the embedded evaluator/interpreter.

Comments