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

时间:2009-08-20 05:46:15

标签: c++

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

5 个答案:

答案 0 :(得分:13)

使用conditinal编译和宏:

#ifdef _DEBUG
   #define LOG( x ) debugPrint( x )
#else
   #define LOG( x )
#endif

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

LOG( blahbhahblah );

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

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

答案 1 :(得分:7)

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

inline void debugPrint(whatever_t wtvr)
{
    #ifdef DEBUG
        Logger::log(wtvr);
    #endif
}

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

答案 2 :(得分:2)

@ sharptooth的答案很好。但是,我通常做的一个小改动是,如果NDEBUG定义,则禁用调试,而不是调整宏 定义:< / p>

#ifndef NDEBUG
   #define LOG( x ) debugPrint( x )
#else
   #define LOG( x )
#endif

NDEBUG宏被定义,然后C assert,我倾向于使用相当自由地断言诸如前置条件和后置条件之类的东西,甚至帮助澄清复杂逻辑的结果,退出编译也是如此。它是“无调试”的标准宏。并且,NDEBUG宏应该已经在发布版本中定义。

请参阅:http://www.opengroup.org/onlinepubs/009695399/functions/assert.html

答案 3 :(得分:1)

我之前使用预处理器做过类似的事情。

#ifndef DEBUG
#define debugPrint
#endif

基本上会删除所有调试行

答案 4 :(得分:1)


#ifdef _DEBUG
#define debugPrint(x) _debugPrint(x)
void _debugPrint(int foo) {
    // debugPrint implementation
}
#else
#define debugPrint(x)
#endif