【发布时间】:2009-06-12 16:26:26
【问题描述】:
我正在尝试开启调试模式,如果
#define DEBUG 1
我想打印一些变量值,如果
#define DEBUG 0
我想要它们。
问题是我有很多实现文件,我希望这个 DEBUG 变量可用于整个项目。现在我需要编辑 foo1.c、foo2.c、foo3.c 中的 DEBUG 变量,这看起来很乏味且容易出错,必须有更好的方法。有什么建议吗?
【问题讨论】:
我正在尝试开启调试模式,如果
#define DEBUG 1
我想打印一些变量值,如果
#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"
【讨论】:
gcc -DDEBUG 而是-dDEBUG?
尝试像 Code Complete 2 的“第 8 章:防御性编程”的第 6 节中建议的史蒂夫·麦康奈尔(Steve McConnel)...将其添加到您的代码中:
#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 语法):
创建一个包含以下内容的文件 debug.h 并将其包含在每个 c 文件中:
#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 是变量,可以是全局(整个程序)或本地/静态的,并且必须在开始时初始化。您可以为整个程序或每个模块定义多个选项。这比带有 level 变量的版本更好,更灵活。
例如。 模块1.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);
....
}
我还将所有 dbgmsk 变量存储在程序启动时读取的配置文本文件中。
【讨论】:
正如@person-b 所说,将此定义指定为编译器选项,例如-D 调试
请注意,为了简化这一点,您应该将代码中的测试从以下位置更改:
#if DEBUG
到:
#ifdef DEBUG
这样您就不必担心指定 0 或 1 值,而是可以依赖于它是否被定义。
【讨论】:
将“#define DEBUG”放在“debug.h”中,并在每个 *.c 文件中#include 该头文件。
【讨论】:
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 调试 #define IFDEBUG if(0)else #别的 #define IFDBUG if(1)else #万一【讨论】: