
Question:
This is my first time working with va_list
and stuff so I don't really know what I'm doing. Okay basically what I have is a bunch of numbers (1, 2, 3, 4, 5) in the function ordered and I get them to print out. This works fine.
#include <iostream>
#include <cstdarg>
using namespace std;
void ordered(int num1, double list ...);
void main()
{
ordered(5, 1.0, 2.0, 3.0, 4.0, 5.0);
}
void ordered(int num1, double list ...)
{
va_list arguments;
va_start(arguments, num1);
list = va_arg(arguments, double);
cout << "There are " << num1 << " numbers" << endl;
do {
cout << list << endl; // prints out 1 then 2 then 3 then 4 then 5
list = va_arg(arguments, double);
} while (list != 0);
// at this point, list = 0
va_end(arguments);
}
the problem is, after the va_end(arguments);
or before it, I would like to get the program to print out my list a second time; basically print out 1, 2, 3, 4, 5 once more, without making another function. I tried to duplicate the code:
va_start(arguments, num1);
do {
cout << list << endl;
list = va_arg(arguments, double);
} while (list != 0);
va_end(arguments);
without success. How can the program to repeat list
once more, or is it not possible to do it again in the same function?
Here is a working implementation:
#include <iostream>
#include <cstdarg>
using namespace std;
void ordered(int num1, ...); // notice changed signature
int main(int,char**)
{
ordered(5, 1.0, 2.0, 3.0, 4.0, 5.0);
return 0;
}
void ordered(int count, ...) // notice changed signature
{
va_list arguments;
va_start(arguments, count);
cout << "There are " << count << " numbers" << endl;
double value = 0.0;
// notice how the loop changed
for(int i = 0; i < count; ++i) {
value = va_arg(arguments, double);
cout << value << endl; // prints out 1 then 2 then 3 then 4 then 5
}
// at this point, list = 0
va_end(arguments);
va_list arg2;
va_start(arg2, count);
cout << "There are " << count << " numbers" << endl;
for(int i = 0; i < count; ++i) {
value = va_arg(arg2, double);
cout << value << endl; // prints out 1 then 2 then 3 then 4 then 5
}
// at this point, list = 0
va_end(arg2);
}
Answer2:From the man page:
<blockquote>va_end()
Each invocation of va_start()
must be matched by a corresponding invocation of va_end()
in the same function. After the
call va_end(ap
) the variable ap is undefined.
Multiple traversals of
the list, each bracketed by va_start()
and va_end()
are possible.
Could you show the code where you <em>tried that but it didn't work</em>?
NB. See also va_copy
, with which you can make a duplicate of arguments
before (destructively) traversing it, and then also traverse the duplicate.
The simple answer (ignoring how varargs really works, I find it hard to find a valid use case outside of printf
) is to copy the arguments yourself. Well, actually a simpler answer would be not to use varargs at all... Why are you not passing a container (or in C++11 using an initializer_list
?)