I want to implement a function which has a variable number of arguments. This function allows me to call another function using the list of optional arguments. The purpose of this function is to call any function depending on some conditions (depending on the called functions, if the two first arguments are equal, we call the function). My problem is, the functions that can be called don't have the same number of arguments and thus, I don't know how to pass the arguments everytime I have a different function
For example, if I have this:
void func(int value_to_compare, int compared_value, int arg_number, char *arg_types, char *function_name, ...)
I can call it like:
char arg1;
int arg2, arg3;
int condition1;
func(condition1, 1, 1, "c", func1, arg1);
func(condition1, 0, 2, "ci", func2, arg1, arg2);
func(arg2, 0 , 3, "cii", func3, arg1, arg2, arg3);
and the functions called are like:
func1(char);
func2(char, int);
func3(char, int, int);
I try to explain more, if I have for example:
struct element_list {
char *element_type;
char *element_name;
}
the structures in my case have a big number of elements, the condition must be passed as an argument to the function, and the condition value depends on a context, so I have to be able to call 'func' in any context, I just give the condition and the value, and then a function will be called with the corresponding arguments, so it will be something like
func(element_list.element_type, "CHAR", func1, "s", element_list.element_name);
in addition to that, I have a huge number of functions, and a huge number of conditions, so I need something that is as generic as possible.
Whatever you're doing, right now you are working around the type system. There's no typesafe way of doing what you want in C.
Having that in mind:
One possible solution is to make all that functions of the same type: typedef void my_func_type(void*) and let each function "decrypt" the parameter on its own.
Another solution is to rethink your design - and this is the solution I sincerely recommend to you. But first you'd need to say a bit more on what you want to achieve here... A good starting point would be to show how exactly you intend to use such functionality. Chances are that you'll end up not needing this at all...
Continued, #1
From what I've understood, you'd want to write such func that this code
char arg1;
int arg2, arg3;
int condition1;
func(condition1, 1, 1, "c", func1, arg1);
func(condition1, 0, 2, "ci", func2, arg1, arg2);
func(arg2, 0 , 3, "cii", func3, arg1, arg2, arg3);
would behave like:
if (condition1 == 1) func1(arg1);
if (condition1 == 0) func2(arg1, arg2);
if (arg2 == 0) func3(arg1, arg2, arg3);
Frankly... The best way is to write it just like this. :-)
Since you're asking this question, chances are you want something more complicated that. The situation is like this: you want to build some abstraction over the control flow of your code. This is where the functional programming style comes in handy... In fact, in C++ the thing would be simple (well, not really trivial, but do-able in a type-safe and portable way, with some template magic strange functions with bind in their names).
We're talking about C not C++, no templates, no functors... so the matter is probably more complicated than that. But first things first- what stops you from using the simple solution with if's? Answering this question is a good start.
You have two choices. The preferred one is to pass your input via a struct that has an input type and various values defined for that type of input. Then you just pass the struct to your function (by reference/pointer).
The second option is to format the arguments so that you can read them using va_start, va_arg, and va_end. To use this, you would need to know the type of the next arg, so you would need to have that passed as an input. You also need to know in advance when the last arg is reached, so again, you'll need to pass that as an input. This is the same way printf works, and why you need to pass the format string to printf.
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