Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I fill a va_list

Tags:

If I have a va_list I know how to extract all its elements:

void printInts(int n,...)
{
    va_list va;
    va_start(va, n);
    for(unsigned int i=0; i<n; i++)
    {
        int arg=va_arg(va, int);
        printf("%d",arg);
    }
    va_end(va);
} 

So when I call printInts(3,1,2,3) the va_list get filled of all the parameters.
But how do I manually fill a va_list without using va_start? I mean that I want something like:

va_list va;
push_arg(va, int, 5); // And so on until I fill all parameters
...

I need this because there is a function that accept a va_list as argument, and I don't know how to fill that va_list of all its parameters.

like image 571
Ramy Al Zuhouri Avatar asked Dec 04 '12 13:12

Ramy Al Zuhouri


People also ask

How does Va_list work in C?

In the most usual stack-based situation, the va_list is merely a pointer to the arguments sitting on the stack, and va_arg increments the pointer, casts it and dereferences it to a value. Then va_start initialises that pointer by some simple arithmetic (and inside knowledge) and va_end does nothing.

What is a Va_list in C++?

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.

Where is Va_list defined?

va_list is defined in stdarg. h as http://www.cplusplus.com/reference/cstdarg/va_list/ states. You can refer to the book "The Standard C Library" by Plauger if you need to know the ins and outs of the std libc.

What is a Variadic function in C?

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.


2 Answers

There's no ability to fill a va_list explicitly.

You should write a wrapper function. Say you need to call your function foo, instead of manually filling in a va_list, you define a new function like so:

void call_foo(int arg1, ...)
{
   va_list ap;
   va_start(ap, arg1);
   foo(arg1, ap);
   va_end(ap);
}

Now you can call foo, which takes a va_list, however you like, by doing e.g. call_foo(1,2,3,4);, call_foo(1, 1, "Hello"); etc.

This will only allow you to specify the arguments at compile time, you can't build the arguments at runtime.

like image 122
nos Avatar answered Sep 27 '22 20:09

nos


Normally, these functions come in pairs. If you have a "va-accepting" function, it is easy to create another one:

void printInts_v(int n, va_list ap)
{
    unsigned int i=0;
    for(i=0; i<n; i++)
    {
        int arg=va_arg(ap, int);
        printf("%d", arg);
    }
}

This function can be called this way:

void printInts(int n,...)
{
    va_list ap;
    va_start(ap, n);
    printInts_v(n, ap);
    va_end(va);
}

But I don't think there is a way to portably pre-fill a va_list for later use.

If you work on one architecture and portability is not an issue, you could craft something on your own, however. How exactly to do that is platform-specific.

like image 36
glglgl Avatar answered Sep 27 '22 19:09

glglgl