2009-06-12 19 views
22

我想有一个调试模式上,所以如果的#define DEBUG 1

#define DEBUG 1 

我想给printf一些变量值,如果

#define DEBUG 0 

我想他们。

问题是我有很多实现文件,我希望这个DEBUG变量可用于整个项目。现在我需要编辑foo1.c,foo2.c,foo3.c中的DEBUG变量,这似乎很乏味且容易出错,并且必须有更好的方法。有什么建议么?

回答

70

编译时,您应该能够为您的编译器指定一个选项。例如,您可以拨打-DDEBUG选项来拨打GCC。

在这种情况下,你会用更好:

#ifdef DEBUG 
#endif 

或:

#if defined(DEBUG) 
#endif 

如果这不是你现在正在做的方式。我很惊讶你的项目没有全局头文件。沿线的东西:

#ifdef DEBUG 
#undef DEBUG 
#endif 
#define DEBUG 1 

在一个名为“debug.h”的文件中。在你的C程序中,可以使用#include "debug.h"

+1

+1。这是做到这一点的最佳方式。 – Brian 2009-06-12 16:29:43

+4

它不是`gcc -DDEBUG`而不是`-dDEBUG`吗? – 2009-06-12 16:29:55

+0

@Alan:好点! – 2009-06-12 16:30:52

4

将“#define DEBUG”放在“debug.h”中,并在每个* .c文件中包含该头文件。

1

试试这个。

在第一个文件,你要包含:

#define DEBUG 

然后,每当你想拥有调试代码,这样做:

#ifdef DEBUG 
do some stuff 
#endif 

这也可以防止您的调试代码制作它变成发布代码。

4

正如@ person-b所述,将该定义指定为编译选项,例如,

#if DEBUG 

到:-D DEBUG

不过请注意,为了简化这个你应该在你的代码更改测试

#ifdef DEBUG 

这样你就不必担心指定一个0或1的值,但可以改为依赖于它的定义与否。

2

samoz和Stephen Doyle提出的检查DEBUG定义而不是其值的建议是一个很好的方法。但是,如果您确实想使用DEBUG = 0,则可以这样做:每次定义DEBUG标志(即,在每个文件),检查现有的定义:

#ifndef DEBUG 
#define DEBUG 1 
#endif 

然后,当您使用选项-DDEBUG = 0你的编译器,中的#define线将永远不会被执行。

13

尝试像史蒂夫·麦康纳在建议的第6部分:从Code Complete 2“第8章的防御性编程” ...添加到您的代码:

#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 

或者,有一个全球性的标题定义这些事情,正如其他建议。

0

我个人很喜欢

 
#ifdef DEBUG 
#define IFDEBUG if(0)else 
#else 
#define IFDEBUG if(1)else 
#endif 
5

至于你的问题的回应,你也可以简单地调用类的编译器:

cc -c -DDEBUG=1 

cc -c -DDEBUG=0 

您必须删除“定义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变量的版本更好,更灵活。

Ex。 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); 
    .... 
} 

我还将所有dbgmsk变量存储在程序启动时读取的配置文本文件中。