问题
I was wondering if it's possible in C to create a variadic function that takes different types of arguments. i.e.
void fillDatabase(char* name, int age){
writeToDatabase(name, age);
}
int main(){
fillDatabase("Paul", 19);
fillDatabase("Herbert");
}
Here I am trying to fill up a database with names and ages. But it's also possible to fill it up with only a name and no age. So I am wondering if I could use the same function for that or if I have to write two different ones?
Online I could only find examples for variadic functions with the same type of arguments.
Thanks in advance!
回答1:
In C99, variadic functions use stdarg(3) operations (generally implemented as macros expanding to compiler-specific magical stuff, e.g. GCC builtins). The first arguments should have some fixed known type, and generally determinates how the other arguments are fetched; in several today's ABIs, variadic function argument passing don't use registers so is less efficient than fixed arity function calls.
In your case, you'll better have several functions. For inspiration sqlite has several open functions.
Notice that POSIX defines some function with one last optional argument, in particular open(2). This is probably implemented as having a function whose last argument can be not supplied.
You could read the ABI specification and the calling conventions specific to your implementation.
BTW, lack of function overloading (like in C++) can be understood as an advantage of C (the function name -which is the only thing the linker care about, at least on Linux & Unix- determines its signature). Hence C++ practically needs name mangling. Read also about dynamic linking and dlopen
回答2:
Check the man page for va_list, va_start, etc.
You declare your function prototype using the ... sequence to denote variable args:
void myfunction(FILE *, *fmt, ...);
For example, we declatre a struct of type va_list (assuming you included stdarg):
struct va_list l;
Initialise the list using the parameter BEFORE the ... - se we'd pass the *fmt pointer to va_start:
va_start(l, fmt);
Now, we can call va_arg to get a value...if we're processing a format string we might have a loop something like this:
while (*fmt) {
/* Look for % format specifier... */
if (*fmt == '%') {
/* Following character can be c for char, i for int or f for float. */
// Opps - advance to char following opening %...
fmt++;
if (*fmt == 'c')
fprintf(stream, "%c", (char) va_arg(l, int));
else if (*fmt == 'i')
fprintf(stream, "%i", (int) va_arg(l, int));
else if (*fmt == 'f')
fprintf(stream, "%f", (float) va_arg(l, double));
... and so on...
You're relying on the character following the % to tell you what data type to expect in the corresponding parameter. Suggest you read the man pages for va_list.
来源:https://stackoverflow.com/questions/33742356/variadic-functions-with-different-types-of-arguments-in-c