我正在尝试开启调试模式,以便如果
#define DEBUG 1
我想要用printf输出一些变量的值,如果
#define DEBUG 0
我想关闭它们。
问题是我有许多实现文件,我希望这个DEBUG变量在整个项目中都可用。目前,我需要在foo1.c、foo2.c、foo3.c中编辑DEBUG变量,这似乎很繁琐且容易出错,肯定有更好的方法。有什么建议吗?
编译时,你可以向编译器指定选项。例如,你可以使用 -DDEBUG
选项调用 GCC。
在这种情况下,最好使用:
#ifdef DEBUG
#endif
或者:#if defined(DEBUG)
#endif
如果这不是你现在的做法,我很惊讶你的项目中没有全局头文件。可以考虑创建一个类似于以下内容的文件:
#undef DEBUG
#define DEBUG 1
在一个名为"debug.h"的文件中。在你的C程序中,你可以使用#include "debug.h"
来包含它。
尝试像Steve McConnel在Code Complete 2的“第8章:防御性编程”的第6节中建议的那样做...将此添加到您的代码中:
#ifdef DEBUG
#if (DEBUG > 0) && (DEBUG < 2)
printf("Debugging level 1");
#endif
#if (DEBUG > 1) && (DEBUG < 3)
printf("Debugging level 2");
#endif
#if (DEBUG > n-1) && (DEBUG < n)
printf("Debugging level n");
#endif
#endif
编译时,请添加此标志(警告:这可能取决于编译器):
-DDEBUG=m
cc -c -DDEBUG=1
或者
cc -c -DDEBUG=0
您必须删除您的文件中的"define DEBUG 1/0" - 或者将其替换为:
#ifndef DEBUG
#define DEBUG 0
#endif
我现在正在使用的是(GCC语法):
create a file debug.h with the following content and include it in each c file:
#ifdef DEBUG
extern FILE *dbgf;
#define D_MIN 0x00010000 // Minimum level
#define D_MED 0x00020000 // Medium level
#define D_MAX 0x00040000 // Maximum level
#define D_FLUSH 0x00080000 // Usefull by a program crash
#define D_TRACE 0x00100000
#define D_1 0x00000001
...
#define D(msk, fmt, args...) if(msk & dbgmsk) { fprintf(dbgf, "%s:",__FUNCTION__); fprintf(dbgf, fmt, ## args ); if(msk & D_FLUSH) fflush(dbgf); }
#define P(msk, fmt, args...) if(msk & dbgmsk) { fprintf(dbgf, fmt, ## args ); if(msk & D_FLUSH) fflush(dbgf); }
#else
#define D(msk, fmt, args...)
#define P(msk, fmt, args...)
#endif
dbgmsk是一个变量,它可以是全局的(整个程序)或者是局部/静态的,并且必须在开始时初始化。你可以为整个程序或每个模块定义多个选项。这比带有级别变量的版本更好、更灵活。
例如:
module1.c:#include "debug.h"
static int dbgmsk; // using local dbgmsk
module1_setdbg(int msk) { dbgmsk = msk; D(D_TRACE,"dbgmsk1=%x\n", dbgmsk); }
foo1() { P(D_1, "foo1 function\n" );
....
}
foo2() {}
...
foo3.c
#include "debug.h"
extern int dbgmsk; // using global dbgmsk
例如,主函数:
#include "debug.h"
FILE *dbgf;
int dbgmsk = 0; // this is the global dbgmsk
int main() {
dbgf = stderr; // or your logfile
dbgmsk = D_MIN;
module1_setdbg(D_MIN|D_MED|D_TRACE|D_1);
....
}
正如@person-b所说,将此定义指定为编译器选项,例如 -D DEBUG。
请注意,为了简化此过程,您应该更改代码中的测试,从而避免以下情况:
#if DEBUG
to:
#ifdef DEBUG
来自samoz和Stephen Doyle的建议是检查DEBUG的定义是否存在,而不是它的值,这是一个好建议。然而,如果你真的想使用DEBUG=0,那么你可以这样做:每次你定义DEBUG标志(即在每个文件中),都要检查是否存在已定义:
#ifndef DEBUG
#define DEBUG 1
#endif
然后,当您使用编译器选项 -DDEBUG=0 时,#define 行将永远不会被执行。
可以试试这个。
在你将要包含的第一个文件中:
#define DEBUG
每当您想要调试代码时,请执行以下操作:
#ifdef DEBUG
do some stuff
#endif
这也可以防止您的调试代码进入发布的代码中。
我个人喜欢
#ifdef DEBUG #define IFDEBUG if(0)else #else #define IFDEBUG if(1)else #endif
gcc -DDEBUG
而不是-dDEBUG
吗? - Alan Haggai Alavi