Say I have a C++ function debugPrint(int foo). How can I most conveniently strip that from release builds? I do not want to surround every call to debugPrint with #ifdefs as it would be really time consuming. On the other hand, I want to be 100% sure that the compiler strips all the calls to that function, and the function itself from release builds. The stripping should happen also, if it's called with a parameter that results from a function call. E.g., debugPrint(getFoo());. In that case I want also the getFoo() call to be stripped. I understand that function inlining could be an option, but inlining is not guaranteed to be supported.
Use conditinal compilation and a macro:
#ifdef _DEBUG
#define LOG( x ) debugPrint( x )
#else
#define LOG( x )
#endif
Define _DEBUG
for the debug build and not define it for the release build. Now in release build every
LOG( blahbhahblah );
will be expanded into an empty string - even the parameters will not be evaluated and will not be included into the emitted code.
You can use any already existing preprocessor symbol that is defined in debug build and not defined in release instead of _DEBUG
.
I've done something like this before with the preprocessor.
#ifndef DEBUG
#define debugPrint
#endif
Essentially that will remove all the debug lines
Make the function inline, and inside the function have the #ifdef's, like this:
inline void debugPrint(whatever_t wtvr)
{
#ifdef DEBUG
Logger::log(wtvr);
#endif
}
That way the optimizer will strip the empty function while keeping the code clean.
#ifdef _DEBUG
#define debugPrint(x) _debugPrint(x)
void _debugPrint(int foo) {
// debugPrint implementation
}
#else
#define debugPrint(x)
#endif
@sharptooth's answer is good. One minor change that I normally make, however, is to disable debugging if the NDEBUG
macro is not defined, rather than if a debug macro is defined:
#ifndef NDEBUG
#define LOG( x ) debugPrint( x )
#else
#define LOG( x )
#endif
When the NDEBUG
macro is defined, then C assert
s, which I tend to use rather judiciously for asserting things like preconditions and postconditions or even to help clarify the result of complex logic, drop out of the compilation as well. It's a standard macro for "no debugging". And, the NDEBUG
macro should already be defined in release builds.
See: http://www.opengroup.org/onlinepubs/009695399/functions/assert.html