Suppose I want to make a function that recursively parses a variadic argument list, by letting each invocation of the function read the next argument? After handing the va_list to the next function, I am not intending to continue using the va_list in the calling function. Is the following code ok:
void VarArgRecursive( va_list args ) {
int nextArg = va_arg(args, int);
if( nextArg != -1 ) {
printf("Next arg %d\n", nextArg);
VarArgRecursive(args);
}
}
void VarArgFunc( int firstArg, ... ) {
va_list args;
va_start(args, firstArg);
VarArgRecursive(args);
va_end(args);
}
int main (int argc, char * const argv[]) {
VarArgFunc(20, 12, 13, -1);
return 0;
}
The code compiles on my system, and the output is as expected:
Next arg 12
Next arg 13
So, is this practice OK? I have searched the list, and found that after handing the va_list over to the next function, the contents of the va_list in the calling function is undefined. That shouldn't matter for my usage, as I will not continue using the va_list after handing it over to the next (well, actually, the same) function. I have also checked this page:
http://c-faq.com/varargs/handoff.html
...which shows that my way of handing over the va_list to the next function is OK. What it doesn't say, is whether it is OK to hand the va_list over to yet another function after reading one arg, and expect the called function to read the next arg. If there are c++ -specific answers to this question, that is also ok, since it will be used in a c++ program.
You can pass it however many times you like, but you cannot "use" the va_list more than once. When consumed, the va_list may be modified and using it again is undefined behavior per the C++ spec.
If you want to use it more than once, call va_copy to clone the va_list prior to consuming it, then pass the copy.
However, in your case what you're doing is acceptable. The problem arises when you attempt to pass the va_list from the beginning to another function.
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