Reputation: 9369
I am using boost::log
as a logger for my C++ program.
During development I often use it this way, for example:
#define LOG(severity) BOOST_LOG_SEV(boost::logger::get(), (severity))
#define LOG_ERR LOG(Severity::error)
#define LOG_INFO LOG(Severity::info)
#define LOG_DEBUG LOG(Severity::debug)
where BOOST_LOG_SEV
is the facility provided by boost::log
, while LOG
, LOG_ERROR
, LOG_INFO
, LOG_DEBUG
are shortcuts defined by me.
In short, BOOST_LOG_SEV
dynamically compares the current debugging severity with the severity passed to the macro itself to decide whether to emit the output or not.
This is an example of a program which use the above macros for debugging purposes:
// set at compile time
#define MAX_LOG_SEVERITY Severity::debug
int main() {
// Print all the messages with a
// Severity <= MAX_LOG_SEVERITY defined before compiling
boost::log::set_severity(boost::logger::get(), MAX_LOG_SEVERITY); // set_severity() is fictitious just to give you an idea
// bool err = ...
if (err)
LOG_ERR << "An error occurred";
else
LOG_INFO << "Okay;
LOG_DEBUG << "main() called";
}
Now, when releasing the program for a production environment, debugging messages with a Severity::debug
level do not really make sense. I could hide them from the output by simply decreasing MAX_LOG_SEVERITY
to Severity::info
, but the problem is that the calls made by LOG_DEBUG
will not be removed from the executable code. This has a bad impact on both efficiency and object size.
The code is full of logging statements and I'd really like to preserve the simple use of operator<<()
.
Without touching those statements themselves, is there any better macro definition/trick for LOG_DEBUG
that would make the pre-processor or the compiler (during its optimizations) "skip" or "remove" the debugging statements when MAX_LOG_SEVERITY
is set to the Severity::debug
constant ?
Upvotes: 5
Views: 2643
Reputation: 11691
The accepted answer does not work for me (MSVC 2019, stdc++17).
My solution is a bit whacky though. But the optimization should definitely take care of it:
#ifdef NDEBUG #define LOG_DEBUG if (false) std::cout #else #define LOG_DEBUG if (true) std::cout #endif
Usage:
LOG_DEBUG << ... << std::endl;
Upvotes: 0
Reputation: 15839
@MartinShobe's accepted answer works on:
-O1
and higher-O2
and higher/OPT:REF
Upvotes: 2
Reputation: 146
While I can't make any guarantees, something like this might work. It depends on what your optimizer does and whether or not you have side effects in the parameters to operator<<.
#ifdef NO_LOG_DEBUG
static class DevNull
{
} dev_null;
template <typename T>
DevNull & operator<<(DevNull & dest, T)
{
return dest;
}
#define LOG_DEBUG dev_null
#else
#define LOG_DEBUG LOG(Severity::debug)
#endif
Upvotes: 6
Reputation: 55
Turns off all optimizations in the program and speeds compilation.
/Od or boot_log_stop
Upvotes: -2