?
Solved

va_arg problem

Posted on 2009-05-11
10
Medium Priority
?
1,032 Views
Last Modified: 2013-11-05
I am trying to create a function with a variable argument list. But, the code I have written (see below) is not giving me the first argument of the variable argument list.

The output to the program should be:

1
2
3

but I am getting

2
3
0

where the last value is out of bounds for the ap pointer. I used gcc 4.3.2 and intel ia32 11.0 compilers on Mac OS X 10.5.6, and got the same results on both.

I found that if I add the following line before the first call to va_arg() that I will get the correct output:

ap -= sizeof(size_t);

but I should not need to manually change the pointer before using it.

What am I doing wrong and how can I fix it?

Thank you in advance.
#include <iostream>
#include <stdarg.h>
 
void vatest(const unsigned int n, const size_t args, ...) {
  size_t x;
  va_list ap;
  va_start(ap, args);
 
//  ap -= sizeof(size_t); // I should not need this line!
  for(unsigned int i = 0; i < n; ++i) {
    x = va_arg(ap, size_t);
    std::cout << x << std::endl;
  }
 
  va_end(ap);
}
 
int main() {
  vatest(3, 1, 2, 3);
  return 0;
}

Open in new window

0
Comment
Question by:gandalf79
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
10 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 24357459
There is no need to use 'args' in your argument list, in fact this is what is causing the error. The last non-variable argument is 'n', so use this in 'va_start()', e.g.
#include <iostream>
#include <stdarg.h>
 
void vatest(const unsigned int n, ...) {
  size_t x;
  va_list ap;
  va_start(ap, n);
 
  for(unsigned int i = 0; i < n; ++i) {
    x = va_arg(ap, size_t);
    std::cout << x << std::endl;
  }
 
  va_end(ap);
}
 
int main() {
  vatest(3, 1, 2, 3);
  return 0;
}
 
Output:
 
$ vatest
1
2
3

Open in new window

0
 
LVL 9

Expert Comment

by:wellhole
ID: 24357470
You're passing the parameters wrong. Get rid of argument args and use n as the size for va_start.
0
 
LVL 2

Author Comment

by:gandalf79
ID: 24357628
Thanks for the quick response. I made the following changes and it work perfectly now.

void vatest(const unsigned int n, ...) {
  // ...
  va_start(ap, n);
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:jkr
ID: 24357641
Um, may I ask what was wrong with my - a bit more complete - answer?
0
 
LVL 2

Author Comment

by:gandalf79
ID: 24357818
I am sorry, I accidentally over looked your solution. When I looked at it, I thought your code was my code. I will attempt to rectify the situation.
0
 
LVL 2

Author Comment

by:gandalf79
ID: 24357864
Please, I am looking but I don't see how I can modify the accepted answer. =(

Had I not overlooked your solution, I would have given you credit for the question since yours is more complete. Thank you for your understanding.
0
 
LVL 2

Author Closing Comment

by:gandalf79
ID: 31580262
Thank you for your help and the quick response.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question