Olympian
Olympian

Reputation: 768

C\C++ Preprocessor different arg for overloaded macros

I want to realize logging in my project. I have macro, smth like

__LOG_TRACE(lg, expr,...) LOG_TRACE_STREAM(lg) << expr;

So I want to realize interface for this macro - another macro, but I want to support 2 types:

LOG_TRACE(msg);
LOG_TRACE(my_logger, msg);

I have some global logger, and first macro will write msg using global logger. Second macro will take my_logger and write msg using it.

I can make it with LOG_TRACE(msg, my_logger); - but it's not good, it's harder to read in code. Order of arguments in __LOG_TRACE is not necessary.

Upd: I don't mean overloading macros. Look - for example I can do this

#define LOG_TRACE(...) __LOG_TRACE(__VA_ARGS__, current_active)

Now I can write

LOG_TRACE(msg);
LOG_TRACE(msg, logger);

But I want not msg,logger and logger,msg

Upvotes: 0

Views: 301

Answers (5)

Jens Gustedt
Jens Gustedt

Reputation: 78923

__VA_ARGS__ is an extension to the current C++ standard, but if you are willing to play with this P99 has a lot of utility macros to achieve what you want. In particular macros that implement conditionals according to the number of arguments they are called.

#define LOG_TRACE(...)                    \
P99_IF_EQ_1(P99_NARG(__VA_ARGS__))        \
(LOG_TRACE_(my_logger, __VA_ARGS__))      \
(LOG_TRACE_(__VA_ARGS__))

P99 is not really C++ compatible, so you'd have to adapt things a bit.

BTW, identifiers that start with _ and a capital letter or another underscore are reserved by C and C++. Double underscores in general are not allowed for C++ because they could interfere with name mangling. So you'd better chose a different name for your base macro.

Upvotes: 0

Roman A. Taycher
Roman A. Taycher

Reputation: 19487

Why not make it a function + do and stringify expression macro?

#define DO_AND_RETURN_STRING_EXPR(x) (x,#x)

ov(DO_AND_RETURN_STRING_EXPR(y))
ov(my_logger, DO_AND_RETURN_STRING_EXPR(y))

(note I haven't tested this code).

Upvotes: 0

Thomas Russell
Thomas Russell

Reputation: 5980

You cannot overload pre-processor macros, your compiler will consider this a redeclaration, rather than an overload, and so only the 2nd will be valid.

You should attempt to name your macros differently, both for readability and because that's the only way you'll get the functionality you want.

Upvotes: 1

Armen Tsirunyan
Armen Tsirunyan

Reputation: 133024

Macro overloading is not allowed in C or C++. But there are workarounds. Here's an article that will help you "overload" your macro: http://cplusplus.co.il/2010/08/31/overloading-macros/

Upvotes: 4

cprogrammer
cprogrammer

Reputation: 5675

If you don't have a variable number of loggers, i recommend you to make a macro for each logger. ex (LOG_TRACE_XML, LOG_TRACE_OUT, LOG_TRACE_TXT). Because simpler is better.

But a better way to do this is to have LOG_TRACE_ERROR/ LOG_TRACE_WARNING/ LOG_TRACE_INFO and manage the way these macros behave using IPC or another macro (SET_MODE(XML/TXT/OUT))

Upvotes: 2

Related Questions