I would like this to work, but it does not:
#include <stdio.h> typedef struct closure_s { void (*incrementer) (); void (*emitter) (); } closure; closure emit(int in) { void incrementer() { in++; } void emitter() { printf("%d\n", in); } return (closure) { incrementer, emitter }; } main() { closure test[] = { emit(10), emit(20) }; test[0] . incrementer(); test[1] . incrementer(); test[0] . emitter(); test[1] . emitter(); }
It actually does compile and does work for 1 instance ... but the second one fails. Any idea how to get closures in C?
It would be truly awesome!
Although C was created two decades after Lisp, it nonetheless lacks support for closures.
Closures are useful because they let you associate data (the lexical environment) with a function that operates on that data. This has obvious parallels to object-oriented programming, where objects allow you to associate data (the object's properties) with one or more methods.
A closure is a programming technique that allows variables outside of the scope of a function to be accessed. Usually, a closure is created when a function is defined in another function, allowing the inner function to access variables in the outer one.
When you define a member method in a traditional OOP language, its closure is "all the members visible in this class". Languages with "proper" closure support simply generalize this, so a function's closure is "all the variables visible here". If "here" is a class, then you have a traditional class method.
Using FFCALL,
#include <callback.h> #include <stdio.h> static void incrementer_(int *in) { ++*in; } static void emitter_(int *in) { printf("%d\n", *in); } int main() { int in1 = 10, in2 = 20; int (*incrementer1)() = alloc_callback(&incrementer_, &in1); int (*emitter1)() = alloc_callback(&emitter_, &in1); int (*incrementer2)() = alloc_callback(&incrementer_, &in2); int (*emitter2)() = alloc_callback(&emitter_, &in2); incrementer1(); incrementer2(); emitter1(); emitter2(); free_callback(incrementer1); free_callback(incrementer2); free_callback(emitter1); free_callback(emitter2); }
But usually in C you end up passing extra arguments around to fake closures.
Apple has a non-standard extension to C called blocks, which do work much like closures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With