While working on a couple of functions that take a variable argument
list, I discovered they were almost completely identical, except for
one line of code. What a great situation for splitting off the common
code to a common function.
Now I know that va_start must be in the function that receives the
variable number of arguments, but must va_end be there as well?
In other words: In pseudo code,
int foo1(char *str, ...)
{
va_list ap;
int ret;
va_start(ap, str);
ret = foocommon(str, ap);
va_end(ap);
return ret;
}
int foo2(char *str, ...)
{
va_list ap;
int ret;
/* code unique to foo2 goes here */
va_start(ap, str);
ret = foocommon(str, ap);
va_end(ap);
return ret;
}
int foocommon(va_list ap)
{
/* handle va_arg here */
return foocommon status value;
}
Or can va_end be placed in foocommon, allowing foo1 and foo2 to end
with return foocommon(str, ap); ?
DSF
The 1999 ISO C standard says, in section 7.15.1, that ``Each invocation of the
va_start or va_copy macros shall be matched by a corresponding invocation of
the va_end macro in the same function.''
Moreover ``The va_end macro facilitates a normal return from the function ...''.
If you have va_start in a function, you can't make a tail call to the common
function, since you haven't used va_end to facilitate a normal return.
Yes. N1336, 7.15.1p1, "...Each invocation of the va_start and
va_copy macros shall be matched by a corresponding invocation
of the va_end macro in the same function."
--
Peter
N1336 is an early draft of C201X, and has no real official standing.
However N1256 7.15.1p1 has the same wording.
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
> While working on a couple of functions that take a variable argument
> list, I discovered they were almost completely identical, except for
> one line of code. What a great situation for splitting off the common
> code to a common function.
>
> Now I know that va_start must be in the function that receives the
> variable number of arguments, but must va_end be there as well?
Yes.
> Or can va_end be placed in foocommon, allowing foo1 and foo2 to end
> with return foocommon(str, ap); ?
No.
7.15.1p1:
> Each invocation of the va_start or va_copy macros shall be matched by a
> corresponding invocation of the va_end macro in the function accepting a
> varying number of arguments.
To all who answered:
That's what I figured. I just wanted to make sure.
Thanks!
DSF
That's true. But it's easy enough to put the tail call one
function down, and everything's copacetic. As a general
rule functions that use va_start/va_end should be written
as simple wrappers, calling an inner function that does
the real work.