4

I'd like to create a function "lazy" which accepts a function with an undetermined number of arguments as parameter. What type do I need or which casts have to be done?

Then I want to execute that thing later in function "evaluate". How do I then pass the arguments I passed before to the "lazy" function to the passed function pointer?

Some code to illustrate my problem:

char *function_I_want_to_call(void *foo, type bar, ...);
// the arguments are unknown to lazy() and evaluate()

typedef struct {
    ??? func;
    va_list args;
} lazy_fcall;

void lazy(lazy_fcall *result, ??? func, ...) {
// which type do I need here?
    va_start(result->_args, fund);
    result->func = func;
}

void *evaluate(lazy_fcall *to_evaluate) {
    return to_evaluate->func(expand_args(to_evaluate->args));
    // what do I have to write there to expand the va_list? It's C, not C++11...
}

int main () {
    lazy_fcall lazy_store;
    lazy(&lazy_store, function_I_want_to_call, "argument_1", "argument_2");
    // ...
    printf("%s", (char *)evaluate(&lazy_store));
}

Or is something like this just impossible? Which other possibilities exist?

bwoebi
  • 23,637
  • 5
  • 58
  • 79
  • possible duplicate of [Passing an ellipsis to another variadic function](http://stackoverflow.com/questions/695982/passing-an-ellipsis-to-another-variadic-function) – hivert Oct 30 '13 at 11:40
  • 1
    @hivert no duplicate. The other function hasn't to be variadic. – bwoebi Oct 30 '13 at 12:25

1 Answers1

3

You can't expand a va_list into separate arguments. The function you want to call have to be able to take a va_list as argument. See e.g. printf versus vprintf.


Also, as noted by caf, you can't store a va_list, as the arguments "pointed" to by it will not be valid once the lazy function returns. Attempting to use the va_list will lead to undefined behavior and all kinds of weirdness.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Hmm. I want to call some functions I use somewhere else too and so doesn't accept a va_list as argument. No alternatives? – bwoebi Oct 30 '13 at 11:35
  • @bwoebi No, not in standard C. Your compiler *might* have something (read its documentation about extensions), or you might be able to hack something together, possibly using assembler, but don't be surprised if it breaks. – Some programmer dude Oct 30 '13 at 11:37
  • Your only reasonable alternative is to turn your one function into two functions; the primary one is variadic and the secondary uses a va_list argument. In order to DRY, your new primary function will extract the va_list and then just call the second to perform the logic. – mah Oct 30 '13 at 11:37
  • @mah Yes, that's how e.g. `printf` works. It just creates a `va_list` and passes it to `vprintf`. – Some programmer dude Oct 30 '13 at 11:38
  • 2
    Even if you had a version of `function_i_want_to_call()` that takes `va_list`, you can't use the `va_list` started in `lazy()` after that function exits. – caf Oct 30 '13 at 11:41
  • @mah ok, fine. I hoped to be able to do so without creating intermediary functions. Seems to not work then (without relying on extensions, what I'm not allowed to.) – bwoebi Oct 30 '13 at 12:29