ech*_*cho 4 c debugging macros
我打算让自己得到一个整洁的C调试宏,不确定我真正想要的是什么(并且在涉及宏时无能为力)我转向谷歌.一段时间后,我现在认为我知道我想要什么,但不知道它是如何工作的.我没有太多运气获得有关宏和调试技术的正确信息.
我过去一直在使用的是这样的:
#ifdef DEBUG
#define DBG(x) printf x
#else
#define DBG(x) /* nothing */
#endif
Run Code Online (Sandbox Code Playgroud)
问题是它可能变得非常混乱,最终你最终会评论出旧的调试消息,尽管你以后可能会需要它们.
我找到的最好的例子来自高级c课程的一些幻灯片,可以在这里找到:http: //www.mpi-inf.mpg.de/departments/rg1/teaching/advancedc-ws08/script/lecture07.pdf (相关部分是幻灯片19-23,但大部分都包含在下面)
作为演讲幻灯片,他们不幸需要一些解释.但是他们提到的东西看起来非常有用:
DBG((MOD_PARSER , "z = %d\n", z));
Run Code Online (Sandbox Code Playgroud)
其中MOD_PARSER是调试模块/类别,其余参数是给printf的.
而DBG的实现:
#ifdef PRGDEBUG
#define DBG(x) dbg_printer x
#else
#define DBG(x) /* nothing */
#endif
void dbg_printer(int module , const char *fmt, ...);
Run Code Online (Sandbox Code Playgroud)
问题#1是编写dbg_printer函数,我不知道如何将可变数量的参数传递给printf语句.
幻灯片继续讨论如何优雅地添加新模块,我相当确定我根本不理解这一点,但无论如何......
*How to add new modules elegantly
*Add a file debug_modules.def
ADD_MOD(0, PARSER)
ADD_MOD(1, SOLVER)
ADD_MOD(2, PRINTER)
Run Code Online (Sandbox Code Playgroud)
...
*“Generate” an enum with debug modules: debug.h
...
#define ADD_MOD(num, id) MOD_ ## id = 1 << num,
enum _debug_modules_t {
#include "debug_modules.def"
};
#undef ADD_MOD
...
Run Code Online (Sandbox Code Playgroud)
...
*Preprocessor yields enum _debug_modules_t {
MOD_PARSER = 1 << 0,
MOD_SOLVER = 1 << 1,
MOD_PRINTER = 1 << 2,
};
Run Code Online (Sandbox Code Playgroud)
我不明白你为什么要左移这些枚举元素的值,我错过了一些漂亮的技巧?
除了上面的幻灯片,我还没有看到一个例子或文章/帖子/甚至提到这一点,所以也许这甚至不适合我的目的.这听起来合理吗?实际使用的技术类似吗?
到目前为止,问题是如何实现dbg_printer以及调试模块枚举应该如何工作,但看看我可能误解了可能发生变化的一切:(
我不明白你为什么要左移这些枚举元素的值,我错过了一些漂亮的技巧?
这很可能是因为通过按位或连接它们可以指示多个元素.
我首选的调试日志宏没有模块特异性,但是将文件名和行号添加到输出中并且相对简单:
#ifdef DEBUG
#define DLOG(fmt, args...) printf("%s:%d "fmt,__FILE__,__LINE__,args)
#else
#define DLOG(fmt, args...)
#endif
Run Code Online (Sandbox Code Playgroud)
编辑:这更像我现在使用的,基于下面的评论(__PRETTY_FUNCTION__和##__VA_ARGS__)和这个Q&A(do {} while (0)):
#ifdef DEBUG
#define DLOG(fmt, ...) printf("%s:%d "fmt, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define DLOG(fmt, ...) do {} while (0)
#endif
Run Code Online (Sandbox Code Playgroud)