如何在C++编译期间剥离调试代码?

juv*_*nis 4 c++

假设我有一个C++函数debugPrint(int foo).我怎样才能最方便地从发布版本中删除它?我不想用#ifdef包围每次调试debugPrint,因为它真的很耗时.另一方面,我希望100%确保编译器剥离对该函数的所有调用,并从发布版本中删除函数本身.如果使用函数调用产生的参数调用它,也应该发生剥离.例如,debugPrint(getFoo());. 在这种情况下,我也希望剥离getFoo()调用.我理解函数内联可能是一种选择,但不保证支持内联.

sha*_*oth 13

使用conditinal编译和宏:

#ifdef _DEBUG
   #define LOG( x ) debugPrint( x )
#else
   #define LOG( x )
#endif
Run Code Online (Sandbox Code Playgroud)

定义_DEBUG调试版本,而不是为发布版本定义它.现在发布版本

LOG( blahbhahblah );
Run Code Online (Sandbox Code Playgroud)

将被扩展为空字符串 - 即使参数也不会被评估,也不会包含在发出的代码中.

您可以使用在调试版本中定义但未在发行版中定义的任何现有预处理器符号,而不是_DEBUG.

  • 这很危险且容易出错.`int x = 0; LOG(x + = 2); use(x);`如果打开"release"或"debug"模式,`的行为会有所不同. (6认同)
  • 我会避免将半冒号放在debugPrint的末尾,并强制用户将它放在LOG语句的末尾.否则会出现问题. (3认同)
  • 如果你想缓解问题LiraNuna指出试试:#define LOG(x)(void)x在else分支.... (3认同)
  • 是的,它会的.在这个世界上没有任何东西是免费的. (2认同)

Lir*_*una 7

使函数内联,函数内部有#ifdef,如下所示:

inline void debugPrint(whatever_t wtvr)
{
    #ifdef DEBUG
        Logger::log(wtvr);
    #endif
}
Run Code Online (Sandbox Code Playgroud)

这样,优化器将在保持代码清洁的同时剥离空函数.

  • @sharptooth,他们必须使用此解决方案进行评估.但是,如果评估改变了程序的运行方式(即副作用),那么问题就是对记录器功能的调用不仅仅是记录. (3认同)
  • 这是否可以保证不评估函数参数? (2认同)