Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it OK to recursively parse the args in a va_list?

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.

like image 428
Balthazar Avatar asked Nov 13 '22 07:11

Balthazar


1 Answers

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.

like image 143
Mahmoud Al-Qudsi Avatar answered Dec 22 '22 00:12

Mahmoud Al-Qudsi