5

我正在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_SEV,提供的设施在哪里boost::log, 而LOG, LOG_ERROR, LOG_INFO,LOG_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_SEVERITYSeverity::info,但问题是LOG_DEBUG不会从可执行代码中删除由 发出的调用。这对效率和对象大小都有不良影响。

代码中充满了日志语句,我真的很想保留operator<<().

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

4

4 回答 4

6

虽然我不能做出任何保证,但这样的事情可能会奏效。这取决于您的优化器所做的事情以及您对 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
于 2013-04-16T03:28:58.033 回答
2

@MartinShobe 接受的答案适用于:

  • g++ (4.7.2)-O1及更高版本
  • clang++ (3.4)-O2及更高版本
  • 带有链接器标志的 Visual Studio (2008)/OPT:REF
于 2014-05-29T02:22:25.863 回答
0

接受的答案对我不起作用(MSVC 2019,stdc++17)。

我的解决方案有点古怪。但是优化绝对应该照顾它:

#ifdef NDEBUG
#define LOG_DEBUG if (false) std::cout
#别的
#define LOG_DEBUG if (true) std::cout
#万一

用法:

LOG_DEBUG << ... << std::endl;
于 2021-03-29T13:30:37.690 回答
-2

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

/Od 或 boot_log_stop

于 2013-04-16T03:04:05.727 回答