First argument is wrong when passing __VA_ARGS__

0

I'm trying to pass __ VA_ARGS __ to a function. For some reason the first argument is always wrong (seems like an address):

#define PRINTF_ERROR(format, ...)  {\
        PrintfError(format, __FUNCTION__, ##__VA_ARGS__);\
}

void PrintfError(const char* format, const char* function, ...)
{
    va_list args;
    va_start(args, format);
    printf("%s(): ", function);
    printf(format, args);
    va_end(args);
} 

For example, when trying to print the same variable: "A = 0x20005524 A = 0x00000007"

Does anybody know why? Thanks

c
macros
variadic-functions
asked on Stack Overflow Aug 17, 2017 by Orit A

3 Answers

3

There are two problem here.

First, va_start expects the last named parameter of the current function as its second parameter. In this case that would be function.

The second issue is that you're passing a va_list into printf. You should be calling vprintf instead.

void PrintfError(const char* format, const char* function, ...)
{
    va_list args;
    va_start(args, function);   // pass "function" instead of "format"
    printf("%s(): ", function);
    vprintf(format, args);      // call vprintf
    va_end(args);
} 
answered on Stack Overflow Aug 17, 2017 by dbush
1

You've got the order of your parameters wrong. The one you pass to va_start() has to be the one before the ... because it's used to work out where the extra arguments start

So your function should look like this...

void PrintfError(const char* function, const char* format, ...)
{
    va_list args;
    va_start(args, format);
answered on Stack Overflow Aug 17, 2017 by Chris Turner
0

From man va_start:

void va_start(va_list ap, last);

[...]

DESCRIPTION

va_start()

[...] The argument last is the name of the last argument before the variable argument list, that is, the last argument of which the calling function knows the type.

So given

void PrintfError(const char* format, const char* function, ...)

just change

  va_start(args, format);

to be

  va_start(args, function);

Also this

  printf(format, args);

(which probably is a typo) should be

  vprintf(format, args);

Unrelated to your question, here

#define PRINTF_ERROR(format, ...)  {\
    PrintfError(format, __FUNCTION__, ##__VA_ARGS__);\
}

the curly braces are only half the way to make this safe.

Better do

#define PRINTF_ERROR(format, ...)  do {\
    PrintfError(format, __FUNCTION__, __VA_ARGS__);\
} while (0)

Also no need for the ##.

answered on Stack Overflow Aug 17, 2017 by alk • edited Aug 17, 2017 by alk

User contributions licensed under CC BY-SA 3.0