#define DEBUG 1

Stu*_*Stu 27 c debugging

我正在尝试调试模式,如果

#define DEBUG 1
Run Code Online (Sandbox Code Playgroud)

我想printf一些变量值和if

#define DEBUG 0
Run Code Online (Sandbox Code Playgroud)

我想要他们.

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

Luc*_*nes 78

编译时,您应该能够为编译器指定一个选项.例如,您可以使用该-DDEBUG选项调用GCC .

在这种情况下,您最好使用:

#ifdef DEBUG
#endif
Run Code Online (Sandbox Code Playgroud)

要么:

#if defined(DEBUG)
#endif
Run Code Online (Sandbox Code Playgroud)

如果这不是你现在这样做的方式.我很惊讶你的项目没有全局头文件.有点像:

#ifdef DEBUG
#undef DEBUG
#endif
#define DEBUG 1
Run Code Online (Sandbox Code Playgroud)

在名为"debug.h"的文件中.在您的C程序中,您可以使用包含它#include "debug.h"

  • 是不是`gcc -DDEBUG`而不是`-dDEBUG`? (4认同)
  • nop ... -D是正确的选项(-U表示undef)-d,字母是在编译期间按字母指定的时间进行调试转储 (2认同)
  • 永远不需要序列:#ifdef X/#undef X/#endif; 你只需写一下:#undef X. X未定义时不喜欢的编译器在几年前就已经死了; C89标准要求取消定义未定义的宏不是错误. (2认同)

Pet*_*ete 15

尝试使用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
Run Code Online (Sandbox Code Playgroud)

然后在编译时添加此标志(警告:这可能与编译器有关):

-DDEBUG=m
Run Code Online (Sandbox Code Playgroud)

或者,有一个全局标题定义了这些类型的东西,正如其他人所建议的那样.


bil*_*ill 6

作为对您的问题的回答,您还可以简单地调用编译器,如:

cc -c -DDEBUG=1 
Run Code Online (Sandbox Code Playgroud)

要么

 cc -c -DDEBUG=0
Run Code Online (Sandbox Code Playgroud)

您必须删除文件中的"define DEBUG 1/0" - 或将其替换为:

#ifndef DEBUG
#define DEBUG 0
#endif
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的(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
    
    Run Code Online (Sandbox Code Playgroud)

dbgmsk是变量,可以是全局(整个程序)或本地/静态,必须初始化为start.您可以为整个程序或每个模块定义多个选项.这比具有级别变量的版本更好,更灵活.

防爆.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() {}
...
Run Code Online (Sandbox Code Playgroud)

foo3.c

#include "debug.h"
extern int dbgmsk; // using global dbgmsk
Run Code Online (Sandbox Code Playgroud)

防爆.主要:

#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);
  ....
}
Run Code Online (Sandbox Code Playgroud)

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


Ste*_*yle 5

正如@person-b所说,将此定义指定为编译器选项,例如 -D DEBUG

但请注意,为了简化此操作,您应该将代码中的测试更改为:

#if DEBUG
Run Code Online (Sandbox Code Playgroud)

到:

#ifdef DEBUG
Run Code Online (Sandbox Code Playgroud)

这样您就不必担心指定 0 或 1 值,而是可以依赖它是否已定义。