In addition to the #define
solution which works very well, I'd like to present an alternative using templates
template<bool B>
void log(std::string message){}
template<>
void log<true>(std::string message){log_internal(message);}
#define DEBUG true
#define COMMUNICATION false
...
log<DEBUG>("this message will be logged");
log<COMMUNICATION>("this message won't");
The #define
solution really is great for most cases, but there are some reasons to use this solution:
You may need scoping - i.e. not having your log
devices dirty the global namespace. This solution can be put in a namespace
where the #define
one can't.
You may need stricter control on what can and can't be done. The LOG(x)
define has the problem that anything can be put in the x
- and if the logging is turned off you won't see a problem.
To clarivy - your code might compile and work with
LOG(std::cout << "Here!" << endl);
because this specific log is turned off. But one day 2 years from now someone will turn on the logging and get endl undefined
errors all over the place. Or worse - he may find that turning on logging suddenly requires linking to a library long gone (because that logging specifically called a function defined in this library), or uses a function that has long-since changed interface (or even was removed completely! True story :( )
Edit
I was asked to add this to the answer:
It may seem like there's a function call overhead in cases where you don't log (the empty function). This isn't the case as the compiler optimizes it out. If you want to be sure of this - add an inline
directive to the functions.
Also, you might want to change it from an std::string
to a const char *
just to make sure no string constructor is called - but that too should be optimized out automatically by the compiler.
Anyway, like I said this isn't intrinsically better than the #define
solution. I actually still use the #define
in my projects - but there are some specific instances where this template solution is preferable.
#ifdef ENABLE_WARN \n #define WARN(x) printf(x) \n #else \n #define WARN(x) \n #endif
? – Oliver Charlesworth#ifdef DEBUG ... #endif
everywhere – Dennis Meng