开发者

How to use __VA_ARGS__ inside a C function instead of macro? [duplicate]

This question already has answers here: Closed 12 years ago.

Possible Duplicate:

C/C++: Passing variable number开发者_如何学Go of arguments around

I'm currently using the following macro declared on my C file.

#define COMMON_Print(...) printf (__VA_ARGS__)

Now that call works just fine, but turns out that I need to be able to create a C function that looks something like this:

void COMMON_Print(...)
{    
    printf (__VA_ARGS__);
}

So that function doesn't work, I get an error

"Error : undefined identifier __VA_ARGS__"

The complexity of my project requires to have a function since it's an interface... So how can I get the parameters ... and pass them to the printf function? Or better what am I doing wrong?

Thanks!


Each of the ?printf functions has a corresponding v?printf function which does the same thing but takes a va_list, a variable argument list.

#include <stdio.h>
#include <stdarg.h>

void COMMON_Print(char *format, ...)
{
    va_list args;

    va_start(args, format);
    vprintf(format, args);
    va_end(args);
}

Side note: Notice that va_start takes the name of the last argument before the ... as a parameter. va_start is a macro which does some stack-based magic to retrieve the variable arguments and it needs the address of the last fixed argument to do this.

As a consequence of this, there has to be at least one fixed argument so you can pass it to va_start. This is why I added the format argument instead of sticking with the simpler COMMON_Print(...) declaration.

See: http://www.cplusplus.com/reference/clibrary/cstdio/vprintf/


__VA_ARGS__ is only for macros; variadic functions are rather different. You need to use va_start, va_arg and va_end from stdarg.h to handle them.

First, your function needs at least one named parameter, e.g.:

void COMMON_Print(const char* fmt, ...)

Then you can define a va_list and use va_start to set it:

va_list args;
va_start(args, fmt);
// your code here
va_end(args);

Now you can use args to access the arguments; calling va_arg(args, TYPE) will return the next variadic argument, so you can just keep calling that until you've read all the arguments.

If you're just trying to call printf, there's a printf variant called vprintf that takes the va_list directly:

vprintf(fmt, args);

There is no easy way to call one variadic function from another; you need something like vprintf that takes the whole va_list


__VA_ARGS__ is for macros only.

Chaining the variable number of argument to another function can't be done directly. Instead you have to pass a va_list , and the function you're calling have to take a va_list. Luckily there's a variation of printf that does this, your function have to be written this way:

void COMMON_Print(char *format,...)
{    
  va_list args;
  va_start(args,format);
  vprintf(format,args);
  va_end(args);
}


What you are looking for is the Ellipsis operator.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜