For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > June 2007 > Variadic functions









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Variadic functions
keith@bytebrothers.co.uk

2007-06-21, 10:05 pm


I asked about this in comp.lang.c++, but it is really more suited to
this group.

I have some logging functions, and have to throw a C++ wrapper round
them, and was having trouble figuring out how to pass on variadic
arguments. The following _does_ work, at least on this Sparc running
SunOS 5.6 using gcc.

My question really is am I OK to assume that "..." is synonymous with
a parameter of type va_list? Because that's effectively what I'm
doing here:

extern "C" {
void dprintf(enum e_dlog level, char *format, ...);
}

#include <stdarg.h>
void DLOG::log(enum e_log level, char *fmt, ...)
{
va_list args;
va_start(args, fmt);
dprintf(level, fmt, args);
}

Eric Sosman

2007-06-21, 10:05 pm

keith@bytebrothers.co.uk wrote On 06/20/07 10:56,:
> I asked about this in comp.lang.c++, but it is really more suited to
> this group.
>
> I have some logging functions, and have to throw a C++ wrapper round
> them, and was having trouble figuring out how to pass on variadic
> arguments. The following _does_ work, at least on this Sparc running
> SunOS 5.6 using gcc.
>
> My question really is am I OK to assume that "..." is synonymous with
> a parameter of type va_list? Because that's effectively what I'm
> doing here:
>
> extern "C" {
> void dprintf(enum e_dlog level, char *format, ...);
> }
>
> #include <stdarg.h>
> void DLOG::log(enum e_log level, char *fmt, ...)
> {
> va_list args;
> va_start(args, fmt);
> dprintf(level, fmt, args);
> }


No, this is wrong. There is no way for a variadic
function to pass its own ... arguments to another variadic
function. What you can do instead is to set up a va_list
and pass that to the inner function, which should be non-
variadic and accept a va_list argument. The inner function
can use va_arg to retrieve values from the va_list that was
built in the outer function. See vfprintf() for an example
of how this looks.

Also, you need to execute va_end(args) in the outer
function, after the inner function returns.

Putting it all together:

void dprintf(enum e_log level, char *fmt,
va_list args)
{
/* use va_arg(args, type) to extract values,
* or pass args along to a still more deeply
* nested function like vfprintf() or vsprintf().
*/
}

void DLOG::log(enum e_log level, char *fmt, ...)
{
va_list args;
va_start(args, fmt);
dprintf(level, fmt, args);
va_end(args);
}

--
Eric.Sosman@sun.com
keith@bytebrothers.co.uk

2007-06-21, 10:05 pm

On 20 Jun, 16:28, Eric Sosman <Eric.Sos...@sun.com> wrote:
> k...@bytebrothers.co.uk wrote On 06/20/07 10:56,:
>
> No, this is wrong. There is no way for a variadic
> function to pass its own ... arguments to another variadic
> function. What you can do instead is to set up a va_list
> and pass that to the inner function, which should be non-
> variadic and accept a va_list argument. The inner function


Thanks Eric - that's much clearer. I just needed to add a new
interface which accepted the va_list argument, then do it the way you
described.

Tenderpo40

2007-06-23, 8:40 pm

Helen Hunt and Heather Locklear playing with each other on film!
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com