简体   繁体   中英

C++ Overloading Macros

I saw different solutions and workarounds of overloading macros. But I seem to have difficulties on this one.
I have a PRINT_DEBUG macro that prints to the visual studio debugger:

#define DEBUG_PRINT(message, ...)   _RPTN(0, message "\n", __VA_ARGS__)

Now say i want to overload it like so:

#define DEBUG_PRINT(message)        _RPT0(0, message "\n")
#define DEBUG_PRINT(message, ...)   _RPTN(0, message "\n", __VA_ARGS__)

This of course won't work, as it would pick up the first macro.
So I checked other topics and found this solution and here is what I came up with:

#define PRINT_DEBUG(...) _DEBUG_PRINT_SELECT(__VA_ARGS__, _DEBUG_PRINT2, _DEBUG_PRINT1, ...) (__VA_ARGS__)

#define _DEBUG_PRINT_SELECT(_1, _2, NAME, ...) NAME

#define _DEBUG_PRINT1(message)      _RPT0(0, message "\n")
#define _DEBUG_PRINT2(message, ...) _RPTN(0, message "\n", __VA_ARGS__)

I'm trying to use it like so:

PRINT_DEBUG("My message");
PRINT_DEBUG("My message %s", someString);
PRINT_DEBUG("My message %s %d", someString, someValue);

Do I really have to hard code each one depending on the amount of arguments I have? or is there any creative way of doing this?

The only work around I found, is to just have a single:

#define PRINT_DEBUG(message, ...)   _RPTN(0, message "\n", __VA_ARGS__);

And say I want to print just a message, I have to pass a second parameter in mvsc compilers:

PRINT_DEBUG("My message", NULL);

Any help would be much appreciated! Thanks in advance!

At least in GCC you don't need to overload anything to solve this problem:

#define DEBUG_PRINT(message, ...)   _RPTN(0, message "\n", ## __VA_ARGS__)

https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html :

In standard C, you are not allowed to leave the variable argument out entirely; but you are allowed to pass an empty argument. For example, this invocation is invalid in ISO C, because there is no comma after the string:

 debug ("A message") 

GNU CPP permits you to completely omit the variable arguments in this way. In the above examples, the compiler would complain, though since the expansion of the macro still has the extra comma after the format string.

To help solve this problem, CPP behaves specially for variable arguments used with the token paste operator, '##'. If instead you write

 #define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__) 

and if the variable arguments are omitted or empty, the '##' operator causes the preprocessor to remove the comma before it. If you do provide some variable arguments in your macro invocation, GNU CPP does not complain about the paste operation and instead places the variable arguments after the comma. Just like any other pasted macro argument, these arguments are not macro expanded.

It does depend on what you are using the macro for, but it seems you are doing this the hard way. Normally the only purpose of a macro around "debug output" is so you can switch it off for release builds.
In this case just wrap a normal function in a macro.

#ifdef Debug
#define PRINT_DEBUG PrintDebugMessage
    enum DebugLevel {SERIOUS, MILD, IRRITATING, MISLEADING, etc};
    void PrintDebugMessage(message);
    void PrintDebugMessage(message, ...);
    void PrintDebugMessage(message, DebugLevel, ...);
    // and so on
#else
    // do nothing
    #define DebugPrint(...) 
#endif

Then implement your PrintDebugMessage functions in a special module, you only build in debug builds.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM