我有一个问题。在我的一个项目中,我使用FLAG PRINT来启用/禁用调试printfs。目前我正在使用这样的东西。
#ifdef PRINT
printf("DEBUG");
#endif
将#ifdef置于每个printf之前是一件痛苦的事。所以我想为#ifdef做一个#define,比如
#define DEBUG_PRINT
#define PRINT (#ifdef DEBUG_PRINT)
#define ENDPRINT #endif
这样我可以像
一样使用PRINT
printf("DEBUG");
ENDPRINT
但它给出了编译器错误。你能告诉我一些简化吗?
谢谢,
答案 0 :(得分:2)
标准方式是
#ifdef DEBUG_PRINT
# define is_debug() (1)
#else
# define is_debug() (0)
#endif
#define pr_dbg(fmt, ...) do { \
if (is_debug()) \
printf(fmt, __VA_ARGS__); \
} while (0)
使用gcc时,您可以/应该写
printf(fmt, ## __VA_ARGS__);
处理空args。
在您的代码中,您可以写
pr_dbg("foo=%u\n", foo);
优化程序将在未定义DEBUG_PRINT
时丢弃表达式,但仍将检查调试语句是否存在语法错误。这避免了在例如静音时破坏未定义的变量在#ifdef
子句中使用。
答案 1 :(得分:1)
带
的标题怎么样?#ifdef DEBUG
#define ON_DEBUG(X,...) do { X, __VA_ARGS__; } while( false )
#else
#define ON_DEBUG(X,...) do {} while( false )
#endif
在您的代码中,您只需使用
ON_DEBUG( printf("Hallo, %s", "Welt") );
(do
- while
强制您添加最后一个分号并保护语句,如果(嵌套)if
- 语句,请参阅Aaron McDaid的评论)
答案 2 :(得分:0)
我实际上会完全采用不同的方式。首先定义打开或关闭打印的标志:
// uncomment to turn off debug printing
#define DEBUG_PRINT 1
然后根据DEBUG_PRINT
:
#ifdef DEBUG_PRINT
#define PRINT (X) (printf(x))
#else
#define PRINT (x)
#endif
可以简单地用作:
PRINT("foo");
但实际上,我根本不会做任何这些事情。相反,我有如上所述的开启/关闭标志,然后构建一个执行打印的类:
// comment out to not do debug printing
//#define DEBUG_PRINTING 1
#ifdef DEBUG_PRINTING
class Printer
{
public:
Printer() {}
~Printer()
{
std::cout << mOutput.str() << "\n";
}
template <typename TYPE> Printer& operator<< (const TYPE& val)
{
mOutput << val;
return * this;
}
template <size_t N> Printer& operator<< (const char(&ary)[N])
{
mOutput << ary;
return * this;
}
private:
std::stringstream mOutput;
};
#else
class Printer
{
public:
Printer() {};
template <typename TYPE> Printer& operator<< (const TYPE& val)
{
return * this;
}
template <size_t N> Printer& operator<< (const char(&ary)[N])
{
return * this;
}
};
#endif
int main()
{
Printer() << "My output here. " << 42;
}
在未定义标志的优化版本中,大多数(如果不是全部)代码都将被优化掉。