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);
}