Using a preprocessor guard is definitely the most flexible and common approach. However, when possible, I suggest using an if statement. For example, instead of
void example(int a){
int some_local;
...
#ifdef _DEBUG
std::cout << "In function " << __FUNCTION__ << "(" << a <<")" << std::endl;
#endif
....
}
Assuming ENABLE_DEBUG is defined to be 0 or non-zero, I would use
void example(int a){
int some_local;
...
if(ENABLE_DEBUG) std::cout << "In function " << __FUNCTION__ << "(" << a <<")" << std::endl;
...
}
Since ENABLE_DEBUG is a constant, when ENABLE_DEBUG is 0 the compiler will not generate any code for statements it guards. So, why use this method instead of #ifdef?
- If there are many separate debug statements spread throughout the code, it can be a bit easier to read
- More importantly, the code is always processed for syntactic errors, even if no code is generated. This can be very helpful if the debug code is not frequently enabled. If variables change (e.g. in the above example if the argument a was renamed), then the person making the change will know they have to update the debug statement as well. If #ifdefs are used, then it can hide bit rot until someone needs to enable the debug code and then they have to go and try and fix up the code, something that may not be obvious to them.
Obviously this approach only works for debug statements inside method/function bodies.