C: variable argument list using stdarg.h
I am experimenting with variable argument lists and seeing some strange results...
The piece of code I am testing is:
#include <stdio.h>
#include <stdarg.h>
void foo(int param1, int param2, ...)
{
int param3 = 0;
va_list ap;
va_start(ap, param2);
param3 = va_arg(ap, int);
va_end(ap);
printf("param3: %d\n", param3);
}
int main(void)
{
foo(1,1);
foo(1,1,42);
}
And the output for that snippet is:
param3: -1073748472
param3: 42
For the second call: 'foo(1,1,42)', everything seems to work as expected.
For the first call: 'foo(1,1)', the result look like an uninitialised int, although I do set it to 0 when I first initialise it at the beginning of the function.
I would like to be able to rely on the fact that the resultant variable should have the value 0 if the argument is not called. I would have thought va_arg() would be sensible enough to deal with that but it doesn't seem to be the case.
Any suggestions to deal with that?
开发者_如何转开发Many thanks.
Firstly, I don't see how the fact that you initialize param3
with zero should matter, since you overwrite that value later anyway.
Secondly, trying to "extract" a non-existing variadic argument produces undefined behavior. So, the only way to deal with that is not to attempt to extract the non-existing argument. There's no way to detect whether the argument exists or not. It is the caller's responsibility to inform the function how many variadic arguments it can safely extract.
The problem is that you're reading the value no matter whether it's passed or not. Thus, you're getting whatever junk happens to be on the stack at the offset where the argument was supposed to live.
When using varargs, you have to make sure that the initial arguments you pass make it clear what other arguments are present. printf() does this by counting % signs (although the programmer sometimes gets this wrong, and hilarity ensues)
The better answer is "don't use varargs; find some type-safe way of doing what you need."
精彩评论