Question

How would I pass part of a va_list or copy part into another va_list starting at the nth element?

int main (int x, char**argv) {
    va_list clientArgs;
    va_copy(clientArgs, argv[3]); // get all input parameters after 3rd cmd line arg

    foo(clientArgs);

    va_end(clientArgs);
    ....

Or using the va_copy method ... ?

Was it helpful?

Solution

Any code will not be portable, or even guaranteed to work (undefined behavior and all that)

However, it is possible, as the code below demonstrates:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <stdarg.h>

void VarShowArgs(int n, va_list args)
{
    for(int i=0; i<n; ++i)
    {
        printf("Arg #%d: %d\n", i+1, va_arg(args, int));
    }
}

void ShowArgs_StartAtFourthParam(int n, ...)
{
    va_list args;
    int dummy;

    va_start(args,n);          // n is param #1 (value = 8)
    dummy = va_arg(args, int); // Remove Param #2 from args (value = 1)
    dummy = va_arg(args, int); // Remove Param #3 from args (value = 2)

    // Show arguments starting at Param #4 (which should be value = 3)
    VarShowArgs(n - 2, args);  // Minus 2 because we removed 2 params from the args.

    va_end(args);
}


int main(void)
{
    // First param says how many more args there will be.
    // This function shows the values starting at the 4th argument (value = 3)
    ShowArgs_StartAtFourthParam(8, 1, 2, 3, 4, 5, 6, 7, 8);
    getch();
    return 0;
}

Output

Arg #1: 3
Arg #2: 4
Arg #3: 5
Arg #4: 6
Arg #5: 7
Arg #6: 8

OTHER TIPS

You can't do it directly. The second argument to va_start should be the name of the last parameter before the ellipsis (...) in the function's argument list. Using anything else leads to undefined behaviour at best.

To be able to approximate what you're after, you have to know what the values are at the front of the va_list. You can use va_arg() to read them, and then pass what's left of the va_list to your other function:

void function(int arg1, char *arg2, ...)
{
    va_list args;
    va_start(args, arg2);
    int i = va_arg(args, int);
    double d = va_arg(args, double);
    foo(args);
    va_end(args);
}

Clearly, if the arguments in the variable list are all the same type, you can use a loop to iterate over the first N such arguments. Note that there is no way to find out how many arguments were provided; your code must 'know'. For example, printf() uses the format string to tell it how many arguments were provided (and the type of each argument).

What do you mean "part of a va_list"? The question doesn't really make a lot of sense.

A va_list is an iterator object that allows you to iterate through the arguments to a function one at a time -- va_start initializes it to point to the argument after a specific argument of the current function, while va_arg gets (copies) the currently pointed at argument and increments it to point at the next argument.

In no case does the va_list encapsulate the argument list -- its just an abstract pointer-like object that refers to the argument list.

You can pass a pointer to the va_list object to some other function and have that function call va_arg to process some of the arguments. After it returns, you can then call va_arg to process more arguments, but this isn't making a copy of the argument list in any real sense.

You can use va_copy to copy a va_list in order to have TWO iterators going through the argument list. Each is then independent, so each will see all the arguments after the point at which the va_copy was done.

There's no way to create a va_list object that refers to anything other than the arguments passed to the current function as ...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top