views:

108

answers:

5

Is something like this possible in C?

#include <stdio.h>

void print_str(char *str) {
        printf(str);
}

int main() {

        void (*f_ptr)() = print_str,"hello world";

        f_ptr();

}

//see "hello world" on stdout

In short, I'd like to have a function pointer that "stores" the arguments. The point is that the function pointer can be used later on without needing a reference to the original data.

I could use something like this to couple a function pointer and an argument reference

struct f_ptr {
 void (*f)();
 void *data;
}

void exec_f_ptr(f_ptr *data) {
  data->f(data->data):
}

but wouldn't be as elegant as just calling a function pointer with the argument inside.

A: 

No, that struct is the closest thing you're going to get

Bwmat
+3  A: 

You're basically asking for a closure rather than a function pointer--that is, data and code in one "object." Such objects don't exist in standard C--you can get something similar from Apple's blocks or from anonymous functions in other languages (or from closures outright in the languages that support them) but generally speaking you'll have to construct some data type of your own, as you've discovered.

Jonathan Grynspan
For a large implementation of this structure, the Function pointer and argument, I believe that DIKU and ROM MUD's had this style of structure passing around for a lot of the functions.
maxwellb
+3  A: 

What you want is a closure or a curried function. Unfortunately, C has neither of these. (Apple did introduce closures in its version of C and hopefully they'll be adopted for some future version of the language, but it's not part of C99.)

Chuck
Is a curried function a closure?
Tyler
+2  A: 

printf(str) is asking for format string attack!

Nyan
This should be a comment, not an answer.
jamesdlin
+1  A: 

GLib has support for closures, used mainly for signal callbacks. It's cross platform, and might be worth a look (depending on your requirements). (See also the GLib closure API.)

detly
While interesting, this probably isn't very useful since the normal place you want closures in C is to use with legacy APIs that omit the ability to pass a context themselves - for example, if you want to use `qsort()` but the comparison depends on a parameter and there are enough possible parameters that you can't make a different function for each one.
R..