其中一个原因你报告调试信息stderr
,而不是stdout
因为stdout
可能关闭发送管道和诊断将与实际数据一起进行,混淆了管道的后续阶段。
如果您可能想要重定向输出或添加时间戳(或PID或任何其他信息),则请勿直接使用fprintf()
。调用你自己设计的功能,以你想要的方式处理你想要的信息。
因此,您的宏可能是:
extern void dbg_print(const char *fmt, ...);
#define DEBUG_PRINT(fmt, ...) \
do { if (DEBUG_TEST) dbg_print(fmt, __VA_ARGS__); } while (0)
或者:
extern void dbg_print(const char *func, const char *file, int line, const char *fmt, ...);
#define DEBUG_PRINT(fmt, ...) \
do { if (DEBUG_TEST) dbg_print(__func__, __FILE__, __LINE__, fmt, __VA_ARGS__); } while (0)
这包括信息
例如,我有函数名,文件名和行号这是一个适度复杂的软件包。其中的核心内部例程的是:
/* err_stdio - report error via stdio */
static void err_stdio(FILE *fp, int flags, int errnum, const char *format, va_list args)
{
if ((flags & ERR_NOARG0) == 0)
fprintf(fp, "%s: ", arg0);
if (flags & ERR_STAMP)
{
char timbuf[32];
fprintf(fp, "%s - ", err_time(timbuf, sizeof(timbuf)));
}
if (flags & ERR_PID)
fprintf(fp, "pid=%d: ", (int)getpid());
vfprintf(fp, format, args);
if (flags & ERR_ERRNO)
fprintf(fp, "error (%d) %s\n", errnum, strerror(errnum));
}
调试包装可以调用到用适当的标记,它们的功能,并生成希望的输出。系统的其他部分控制使用的文件流(stderr
是默认设置,但有一个功能可将输出重定向到其他任何流),依此类推。
如果您通过在调试宏中直接使用fprintf()
来限制自己,那么您可以使用fprintf()
可以执行的操作或重新编译所有内容。
另请参阅我对'C#define macro for debug printing'的回答,以获取有关调试宏以及如何使用它们的更多信息(尽管看起来好像您已经在板上说了很多东西)。
+1。很好的解释。 – dicaprio 2011-12-30 07:39:00