I have a function foo(char *n, ...);
I need to get and use all of optional char
parameters.
I had an idea to use
while(va_arg(argPtr, char) != NULL)
{
...
}
to understand when I reach the end of the list. So, will it work, if in function call I'll do foo(n, 't', 'm', '$', NULL);
?
Will NULL
be read as a char by va_arg?
Or maybe there's a more common way to determine the end of list, without adding NULL
as last parameter?
The va_arg() macro retrieves a value of the given var_type from the location given by arg_ptr and increases arg_ptr to point to the next argument in the list. The va_arg() macro can retrieve arguments from the list any number of times within the function.
va_copy() The va_copy() macro copies the (previously initialized) variable argument list src to dest. The behavior is as if va_start() were applied to dest with the same last argument, followed by the same number of va_arg() invocations that was used to reach the current state of src.
va_list is a complete object type suitable for holding the information needed by the macros va_start, va_copy, va_arg, and va_end. If a va_list instance is created, passed to another function, and used via va_arg in that function, then any subsequent use in the calling function should be preceded by a call to va_end.
Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.
There is no direct way for a function that uses va_arg
to determine the number or type(s) of the arguments passed by a given call.
Your proposed method in particular:
while(va_arg(argPtr, char) != NULL)
is incorrect. va_arg(argPtr, char)
yields a value of type char
, while NULL
is a null pointer constant. (NULL
is commonly defined as 0
, which compares equal to the null character '\0'
, but you can't rely on that.)
Any variadic function must have a way for the caller to specify the number and types of arguments. The *printf
functions, for example, do so via the (non-variadic) format string. The POSIX execl*()
functions expect a sequence of char*
arguments; the end of the argument list is marked by the caller with (char*)NULL
. Other methods are possible, but they almost all depend on information given at run time in the arguments. (You could use some other method, such as a global variable. Please don't.)
This places a burden on the caller to ensure that the arguments passed to the function are consistent. The function itself has no way to confirm this. Incorrect calls, like printf("%d\n", "hello")
or execlp("name", "arg1")
have undefined behavior.
One more thing: you can't use va_arg
with an argument of type char
. When you call a variadic function, arguments corresponding to the , ...
are promoted. Integer arguments of types narrower than int
are promoted to int
or to unsigned int
, and arguments of type float
are promoted to double
. If a caller passes an argument of type char
, the function must invoke va_arg(argPtr, int)
.
(In very obscure circumstances that you're not likely to run into, char
can be promoted to unsigned int
. That can happen only if plain char
is unsigned and sizeof (int) == 1
, which implies that a byte is at least 16 bits.)
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