Functions with variable arguments. How does open() work?
I have to write a function that accepts a variable number of arguments, similar to the open() function
int open (const char *filename, int flags[, mode_t mode])
I had a look at the va_list functionality, but how can I find out how many arguments the use开发者_如何学编程r has supplied? I dont want to have a parameter in the function that indicates this.
Being a sort of newbie, where can I look how the open() function is implemented? How does open() know whether the user has supplied the mode argument or not?
Thanks in advance.
You cannot. The caller must either supply a trailing sentinel argument (e.g. a
0
), or explicitly tell the function how many arguments to expect (e.g. the format fields inprintf
).open
knows to expect the third argument because you will have set theO_CREAT
flag in theflags
argument.
Copied straight from the GCC page.
Here is a complete sample function that accepts a variable number of arguments. The first argument to the function is the count of remaining arguments, which are added up and the result returned. While trivial, this function is sufficient to illustrate how to use the variable arguments facility.
#include <stdarg.h>
#include <stdio.h>
int
add_em_up (int count,...)
{
va_list ap;
int i, sum;
va_start (ap, count); /* Initialize the argument list. */
sum = 0;
for (i = 0; i < count; i++)
sum += va_arg (ap, int); /* Get the next argument value. */
va_end (ap); /* Clean up. */
return sum;
}
int
main (void)
{
/* This call prints 16. */
printf ("%d\n", add_em_up (3, 5, 5, 6));
/* This call prints 55. */
printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
return 0;
}
What you're looking for is variadic function implementations. Here is a doc that will walk you through the entire chain.
The short answer to the question, "How does open
know if it was passed two or three arguments?" is: it's magic. The long answer is that the implementation is allowed to do certain things that you are not (within standard C, that is).
Another example is main
. It has two valid prototypes:
int main(void);
and
int main(int argc, char *argv[]); /* or equivalent */
The implementation must allow you to use any of the two, and "deduce", which is the one you used.
The answer to the question, "How can I do something similar in my code?", is: you can't, at least not within the constraints imposed by the C standard.
精彩评论