Variable argument list passed to another function. Where to put va_end?


D

DSF

Hello,

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
 
Ad

Advertisements

P

Peter Nilsson

DSF said:
...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. 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."
 
K

Keith Thompson

Peter Nilsson said:
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."

N1336 is an early draft of C201X, and has no real official standing.

However N1256 7.15.1p1 has the same wording.
 
N

Nobody

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.
 
D

DSF

To all who answered:

That's what I figured. I just wanted to make sure.

Thanks!

DSF
 
Ad

Advertisements

T

Tim Rentsch

Kaz Kylheku said:
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.

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.
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top