By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,515 Members | 1,363 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,515 IT Pros & Developers. It's quick & easy.

Calling variadic funcs

P: n/a

Someone please help me out here - I'm having a 'bad brain' day.

I have a number of C logging functions, prototyped as, say:

extern "C" {
mylog1(char *arg1, char *arg2, char *arg3);
mylog2(char *arg1, char *arg2, ...);
mylog3(char *arg1, ...);
}

What I want to do is throw a C++ wrapper around them. The first case
above is pretty trivial:

MYLOG::one(char *a1, char *a2, char *a3)
{ mylog1(a1, a2, a3); }

For the life of me I can't see how I go about passing the variadic
args for the other two cases!

Jun 20 '07 #1
Share this Question
Share on Google+
8 Replies


P: n/a
<ke***@bytebrothers.co.ukwrote in message
news:11**********************@g4g2000hsf.googlegro ups.com...
:
: Someone please help me out here - I'm having a 'bad brain' day.
:
: I have a number of C logging functions, prototyped as, say:
:
: extern "C" {
: mylog1(char *arg1, char *arg2, char *arg3);
: mylog2(char *arg1, char *arg2, ...);
: mylog3(char *arg1, ...);
: }
:
: What I want to do is throw a C++ wrapper around them. The first case
: above is pretty trivial:
:
: MYLOG::one(char *a1, char *a2, char *a3)
: { mylog1(a1, a2, a3); }
:
: For the life of me I can't see how I go about passing the variadic
: args for the other two cases!

The variadic functions are called in the exact same way,
provided that the function's implementation expects the
corresponding number of parameters, and of the correct type:

extern "C" {
void mylog1(char *arg1, char *arg2, char *arg3);
void mylog2(char *arg1, char *arg2, ...);
void mylog3(char *arg1, ...);
}

void one(char *a1, char *a2, char *a3) { mylog1(a1, a2, a3); }
void two(char *a1, char *a2, char *a3) { mylog2(a1, a2, a3); }
void thr(char *a1, char *a2, char *a3) { mylog3(a1, a2, a3); }

-Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <http://www.brainbench.com

Jun 20 '07 #2

P: n/a
On 2007-06-20 13:15, ke***@bytebrothers.co.uk wrote:
Someone please help me out here - I'm having a 'bad brain' day.

I have a number of C logging functions, prototyped as, say:

extern "C" {
mylog1(char *arg1, char *arg2, char *arg3);
mylog2(char *arg1, char *arg2, ...);
mylog3(char *arg1, ...);
}

What I want to do is throw a C++ wrapper around them. The first case
above is pretty trivial:

MYLOG::one(char *a1, char *a2, char *a3)
{ mylog1(a1, a2, a3); }

For the life of me I can't see how I go about passing the variadic
args for the other two cases!
If you have a C99 compliant compiler take a look at the va_* macros in
stdarg.h. For older compilers look at varargs.h.

--
Erik Wikström
Jun 20 '07 #3

P: n/a
On 20 Jun, 13:38, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-06-20 13:15, k...@bytebrothers.co.uk wrote:
For the life of me I can't see how I go about passing the variadic
args for the other two cases!

If you have a C99 compliant compiler take a look at the va_* macros in
stdarg.h. For older compilers look at varargs.h.
I spotted those, but they appear to require that you know how many
arguments are being passed in. I suppose I can count the format
specifiers in the format string that comes in, and assume that is
equal to the number of following arguments...

Jun 20 '07 #4

P: n/a
ke***@bytebrothers.co.uk wrote:
On 20 Jun, 13:38, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2007-06-20 13:15, k...@bytebrothers.co.uk wrote:
>>For the life of me I can't see how I go about passing the variadic
args for the other two cases!
If you have a C99 compliant compiler take a look at the va_* macros in
stdarg.h. For older compilers look at varargs.h.

I spotted those, but they appear to require that you know how many
arguments are being passed in. I suppose I can count the format
specifiers in the format string that comes in, and assume that is
equal to the number of following arguments...
To be honest, I doubt that you can wrap easily a variable arguments
function as you want. There is a macro __VA_ARGS__ for the variable
arguments macro, but I'm not really sure that you can pass a variable
number of arguments to a function in a compact form with the expressive
power of the language...

Regards,

Zeppe
Jun 20 '07 #5

P: n/a
On 20 Jun, 14:23, Zeppe <zep_p@.remove.all.this.long.comment.yahoo.it>
wrote:
k...@bytebrothers.co.uk wrote:
I spotted those, but they appear to require that you know how many
arguments are being passed in. I suppose I can count the format
specifiers in the format string that comes in, and assume that is
equal to the number of following arguments...

To be honest, I doubt that you can wrap easily a variable arguments
function as you want. There is a macro __VA_ARGS__ for the variable
arguments macro, but I'm not really sure that you can pass a variable
number of arguments to a function in a compact form with the expressive
power of the language...
Well, I'm pretty sure that this isn't correct by any standard, and the
chances of it working on a different platform are probably close to
zero, because I'm relying on "..." being synonymous with a parameter
of type 'va_list', but having said all that, this works:

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

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

Jun 20 '07 #6

P: n/a
ke***@bytebrothers.co.uk wrote:
Well, I'm pretty sure that this isn't correct by any standard, and the
chances of it working on a different platform are probably close to
zero, because I'm relying on "..." being synonymous with a parameter
of type 'va_list', but having said all that, this works:

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

#include <stdarg.h>
void DLOG::log(enum e_dlog level, char *fmt, ...)
{
va_list args;
va_start(args, fmt);
dprintf(level, fmt, args);
}
Well, I have to admit that the standard is quite cryptic in this:

If access to the varying arguments is desired, the called function shall
declare an object (generally referred to as ap in this subclause) having
type va_list. The object ap may be passed as an argument to another
function; if that function invokes the va_arg macro with parameter ap,
the value of ap in the calling function is indeterminate and shall be
passed to the va_end macro prior to any further reference to ap.

I can understand that you are allowed to pass ap as an argument, but
that the function that makes use of the object ap shall invoke the
va_arg with ap, it shouldn't declare a new va_list (as dprintf in your
case does). I think your code is working just by chance, because it
happens that the arguments are aligned in the stack in the correct way
when you call the dprintf function.

Pay attention to that.

Regards,

Zeppe
Jun 20 '07 #7

P: n/a
On Wed, 20 Jun 2007 06:36:04 -0700, keith wrote:
On 20 Jun, 14:23, Zeppe <zep_p@.remove.all.this.long.comment.yahoo.it>
wrote:
>k...@bytebrothers.co.uk wrote:
I spotted those, but they appear to require that you know how many
arguments are being passed in. I suppose I can count the format
specifiers in the format string that comes in, and assume that is
equal to the number of following arguments...

To be honest, I doubt that you can wrap easily a variable arguments
function as you want. There is a macro __VA_ARGS__ for the variable
arguments macro, but I'm not really sure that you can pass a variable
number of arguments to a function in a compact form with the expressive
power of the language...

Well, I'm pretty sure that this isn't correct by any standard, and the
chances of it working on a different platform are probably close to
zero, because I'm relying on "..." being synonymous with a parameter of
type 'va_list', but having said all that, this works:

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

#include <stdarg.h>
void DLOG::log(enum e_dlog level, char *fmt, ...) {
va_list args;
va_start(args, fmt);
dprintf(level, fmt, args);
}
For printf and friends there are vprintf and such which will accept a
va_list argument. Maybe there is a vdprintf wherever dprintf came from.

You also need a va_end(args); at the end of your function.

--
Markus Schoder
Jun 20 '07 #8

P: n/a
Erik Wikström wrote:
>
If you have a C99 compliant compiler take a look at the va_* macros in
stdarg.h. For older compilers look at varargs.h.
stdarg.h is C90, not just C99.
Jun 20 '07 #9

This discussion thread is closed

Replies have been disabled for this discussion.