Home > Blockchain >  How to put a function as an argument with unspecified sub arguments in C?
How to put a function as an argument with unspecified sub arguments in C?

Time:10-06

I am trying to make a function, which will execute a function with the provided sub arguments in C. Like:

int function(void (*func)(), ...) // add as many arguments you want for 'func()'
{
    va_list ptr;

    ...

    func(sub_arguments) // the '...'
}

void *abc(int a) { ... }
void *one(int b, int c) { ... }

int main()
{
   function(abc, 73);
   function(one, 9, 84);
}

Now, is there a way to somehow make a variable list and add it as the arguments and execute it? If so, how?

I know I phrased the question in a very difficult way, but I just don't get how to do this.

CodePudding user response:

You can either extract each argument in function() and make the relevant call:

#include <stdio.h>
#include <stdarg.h>

void abc(int a) {
    printf("abc(%d)\n", a);
}

void one(int b, int c) {
    printf("one(%d,%d)\n", b, c);
}

int function(void (*func)(), ...) {
    va_list ap;
    va_start(ap, func);
    if(func == abc) {
        int a = va_arg(ap, int);
        func(a);
    } else if(func == one) {
        int b = va_arg(ap, int);
        int c = va_arg(ap, int);
        func(b, c);
    }
    va_end(ap);
    return 0;
}

int main() {
    function(abc, 73);
    function(one, 9, 84);
}

Or change your sub-functions to take a va_list, then pass it from function to the sub-function. That is probably the approach I would would take. If want to call your sub-functions directly that write a wrapper for each that accepts a ... argument (like printf() and vpritnf() pair). Note that this requires the sub-functions to have a fixed argument like function() has func.

CodePudding user response:

One option could be to not use a variadic function at all but to use a C11 _Generic selection to call an implementation of function exactly matching the arguments it's supposed to relay on to func:

#include <stdio.h>

int function_impl_1(void(*func)(int), int a) {
    func(a);
    return 0;
}

int function_impl_2(void(*func)(int, int), int a, int b) {
    func(a, b);
    return 0;
}

#define function(X, ...) _Generic((X),               \
                      void(*)(int): function_impl_1, \
                 void(*)(int, int): function_impl_2  \
                                 )(X, __VA_ARGS__)

void abc(int a) {
    printf("abc(%d)\n", a);
}

void one(int b, int c) {
    printf("one(%d,%d)\n", b, c);
}

void two(int b, int c) {
    printf("two(%d,%d)\n", b, c);
}

int main(void) {
    function(abc, 73);
    function(one, 9, 84);
    function(two, 123, 456);
}

Demo

  • Related