views:

185

answers:

2

I have a function which takes variable arguments, something like the following

int log_data (LOG_TYPE eType, ...)
{
    /** some logging related stuff here **/
}

In the header file, I use something like

#ifdef LOGGING_ENABLED
int log_data (int nType, ...);
#else
#define log_data(_x_, ...)
#endif

Basically, the idea is to SWITCH debugging ON & OFF ~~~

  • Problem: The above logic works perfectly fine in Linux & gcc, but errors outs during compilation in Windows VC++.
+3  A: 

Older versions of VC++ do not support variable arguments in macros.

You can use this trick to get around it:

#ifdef LOGGING_ENABLED
#define log_data log_data_impl
#else
#define log_data
#endif

// usage:
log_data(level, ...)

UPDATE - Another possible workaround:

#ifdef LOGGING_ENABLED
#define log_data(P) log_data_impl P // no braces around P!
#else
#define log_data(P)
#endif

// usage: we have to use two braces
log_data((level, ...));
Miroslav Bajtoš
To say the statement "VC++ doesn't support..." is ambiguous. For example, it *does* support it on later versions.
GMan
Good point, I have edited the answer.
Miroslav Bajtoš
You could just say `#ifdef LOGGING_DISABLED #define log_data #endif` and then all calls to `log_data(x, y, z)` would be transformed to `(x, y, z)` and be evaluated in void context, but this wouldn't work if the arguments have side effects (which they probably shouldn't, just for the record).
Chris Lutz
+4  A: 

Variadic macros are relatively new, for example: this reference says that "Support for variadic macros was introduced in Visual C++ 2005." You might have an older version.

Edit: you are declaring log_data if you want debugging, and not if you don't. This means that you have the definition of the function in an #ifdef as well. As long as you're doing this, a solution would be:

int log_data (int nType, ...)
{
#ifdef LOGGING_ENABLED
     /* the code to do logging */
#else
     return 0; /* or whatever */
#endif
}

and in your header file, declare the function as usual:

int log_data (int nType, ...);

This has a disadvantage that the function call exists even when you're not logging, but the advantage is that it will work without preprocessor support for varargs.

Alok
That "disadvantage" should be optimized away by any reasonably modern compiler.
Chris Lutz