Click to See Complete Forum and Search --> : Help with stdarg.h.
SRcoder!
March 23rd, 2004, 11:05 AM
Picked up Programming Windows 5th Edition by Charles Petzold and had a problem understanding some of the code in the second chapter. A friend of mine tried to explain it to me, and I thought I had it untill I tried writting my own program and it came out incorrectly. Here is the code, it should produce an output of 1, yet it produces an output of a very large negative number.
#include <stdarg.h>
#include <iostream>
int minus(int iVariable, int iOne, ... );
int main(void)
{
int iReturn=minus(5, 1, 1, 2);
std::cout<<"The value is: "<<iReturn<<std::endl;
return(0);
}
int minus(int iVariable, int iOne, ...)
{
int iInc(iOne);
va_list id1;
va_start(id1, iOne);
while(iInc!=-1)
{
iVariable-=iInc;
iInc=va_arg(id1, int);
}
va_end(id1);
return(iVariable);
}
Paul McKenzie
March 23rd, 2004, 12:00 PM
Your call must have the last argument of -1 so as to terminate the loop:
int iReturn=minus(5, 1, 1, 2, -1);
//...
while(iInc!=-1) // <-- Look at this line in your function
Regards,
Paul McKenzie
lavut
March 23rd, 2004, 03:13 PM
the normal function call looks like this in assembly if you try to compile the source with option /Fa
push 2
push 1
push 1
push 5
push return address
and the stack will looks like this:
id1 -8
iInc -4 <-----var declared inside funct
ebx 0<---base address
return address +4
5 +8
1 +12 <------id1
1 +16
2 +18
So when you call va_start(id1, iOne), it will fetch the stack address of iOne which is at +12 relative to the base address 0.
Each time you call va_arg(id1, int), id1 is incremented by sizeof (int) which will return the value after iOne in the function parameter list, until it reach the final parameter which is 2 in your example code.But the loop will never stop until it find a value -1 in way down the stack . So that's why you have to put a -1 in your parameter list as Paul suggested so you can exit the loop with the result expected.
hopes this clears up a bit
or you can look inside stdarg.h for the nittygritty details of vastart and va_arg
SRcoder!
March 23rd, 2004, 06:33 PM
Ohh, ok. Thanks I get it, but is there a way to not have to add it. For example have it look for next untill it does not exist? I just compiled the code replacing:
while(iInc!=-1)
with:
while(iInc)
It doesn't look as if it worked. I got a result of a large negative number again using that method. Ohh well. I guess I will just have to remember to terminate the arguments with -1 or what ever I happen to use in my while statement. Thanks, that works perfectly.
Paul McKenzie
March 23rd, 2004, 07:17 PM
Originally posted by SRcoder!
Ohh, ok. Thanks I get it, but is there a way to not have to add it?No. That's how variable argument functions work -- you're responsible to come up with the "stopping" criteria, it isn't automatic. In your case, it was the -1 argument. For a function such as printf( ), the stopping criteria is when the end of the format string is reached by the internal printf() parser.
Regards,
Paul McKenzie
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.