使用宏增加c ++代码详细程度

Mar*_*sne 14 c++ debugging macros

我希望有可能为我的程序的调试目的增加详细程度.当然,我可以在运行时使用开关/标志来做到这一点.但由于我应该在代码中添加所有"if"语句,因此效率非常低.

所以,我想在编译期间添加一个标志,以便在我的代码中包含可选的,通常很慢的调试操作,而不会在不需要时影响程序的性能/大小.这是一个例子:

/* code */
#ifdef _DEBUG_
/* do debug operations here 
#endif
Run Code Online (Sandbox Code Playgroud)

因此,使用-D_DEBUG_进行编译应该可以解决问题.没有它,那部分将不会包含在我的程序中.

另一种选择(至少对于i/o操作)将至少定义一个i/o函数,如

#ifdef _DEBUG_
#define LOG(x) std::clog << x << std::endl;
#else
#define LOG(x) 
#endif
Run Code Online (Sandbox Code Playgroud)

但是,我强烈怀疑这可能不是最干净的方法.那么,你会做什么呢?

Jos*_*eld 18

我更喜欢使用#ifdef真正的函数,以便函数有一个空体,如果_DEBUG_没有定义:

void log(std::string x)
{
#ifdef _DEBUG_
  std::cout << x << std::endl;
#endif
}
Run Code Online (Sandbox Code Playgroud)

这种偏好有三个重要原因:

  1. 如果_DEBUG_未定义,则函数定义为空,并且任何现代编译器将完全优化对该函数的任何调用(当然,该定义应该在该转换单元内可见).
  2. #ifdef警卫只被应用到的代码每次调用时间的一小局部区域,而不是log.
  3. 您不需要使用大量宏,从而避免污染您的代码.

  • 只假设编译器看到了定义!(或LTO,但这是例外而不是此时的规则.)如果定义在不同的TU中,编译器在编译代码时无法知道它没有效果. (7认同)

Bar*_*icz 2

您可以使用宏来更改函数的实现(就像 sftrabbit 的解决方案一样)。这样,代码中就不会留下任何空白位置,并且编译器将优化“空”调用。

您还可以使用两个不同的文件进行调试和发布实现,并让您的 IDE/构建脚本选择合适的一个;这涉及不#defines根本不涉及。只需记住 DRY 规则,并使干净的代码在调试场景中可重用即可。

我想说,他实际上非常依赖于您面临的实际问题。有些问题将有利于第二种解决方案,而简单的代码可能会通过简单的定义更好。