如何从程序中删除日志调试语句

How to remove log debugging statements from a program

本文关键字:日志 调试 语句 删除 程序      更新时间:2023-10-16

我使用boost::log作为我的c++程序的记录器。在开发过程中,我经常这样使用它,例如:

#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)

其中BOOST_LOG_SEVboost::log提供的设施,LOGLOG_ERRORLOG_INFOLOG_DEBUG为本人定义的快捷方式。

简而言之,BOOST_LOG_SEV动态地比较当前的调试严重程度与传递给宏本身的严重程度,以决定是否发出输出。

这是一个使用上述宏进行调试的程序示例:

// 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";
}

现在,在为生产环境发布程序时,使用Severity::debug级别调试消息实际上没有意义。我可以通过简单地将MAX_LOG_SEVERITY减少到Severity::info来将它们从输出中隐藏起来,但问题是LOG_DEBUG所做的调用不会从可执行代码中删除。这对效率和对象大小都有不好的影响。

代码充满了日志记录语句,我真的想保留operator<<()的简单使用。

在不触及这些语句本身的情况下,LOG_DEBUG是否有更好的宏定义/技巧可以使预处理器或编译器(在其优化期间)
MAX_LOG_SEVERITY设置为Severity::debug常数时,"跳过"或"删除"调试语句

虽然我不能做出任何保证,但这样的事情可能会起作用。这取决于你的优化器是做什么的,以及你在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

@MartinShobe的接受答案适用于:

  • g++(4.7.2)与-O1及更高版本
  • clang++ (3.4) with -O2及以上
  • Visual Studio(2008)带有链接标志/OPT:REF

接受的答案不适合我(MSVC 2019, stdc++17)。

我的解决方案有点古怪。但是优化一定要考虑到这一点:

<>之前# ifdef NDEBUG#define LOG_DEBUG if (false) std::cout其他##define LOG_DEBUG if (true) std::cout# endif之前

用法:<>之前LOG_DEBUG & lt; & lt;... & lt; & lt;std:: endl;

关闭程序中的所有优化并加快编译速度。

/Oddiv或boot_log_stop