【问题标题】:#define DEBUG 1#define 调试 1
【发布时间】:2009-06-12 16:26:26
【问题描述】:

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

#define DEBUG 1

我想打印一些变量值,如果

#define DEBUG 0

我想要它们。

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

【问题讨论】:

    标签: c debugging


    【解决方案1】:

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

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

    #ifdef DEBUG
    #endif
    

    或:

    #if defined(DEBUG)
    #endif
    

    如果这不是您现在的做法。我很惊讶您的项目没有全局头文件。大致如下:

    #undef DEBUG
    #define DEBUG 1
    

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

    将其包含在内

    【讨论】:

    • 不是gcc -DDEBUG 而是-dDEBUG
    • nop... -D 是正确的选项(-U 表示 undef) -d 带字母是在编译期间在由字母指定的时间进行调试转储
    • @Alan 我误解了你所说的......我的错:-)
    • @person-b 和@LB:我应该改写我的评论。看起来模棱两可。 :-)
    • 永远不需要序列:#ifdef X / #undef X / #endif;您只需写:#undef X。当 X 未定义时不喜欢这样的编译器几年前就死了; C89 标准要求取消定义未定义的宏不是错误。
    【解决方案2】:

    尝试像 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
    

    或者,像其他人建议的那样,有一个定义这些事情的全局标题。

    【讨论】:

    • 不错的建议,但书名是什么?
    【解决方案3】:

    作为对您的问题的回应,您也可以简单地调用编译器,如下所示:

    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 变量存储在程序启动时读取的配置文本文件中。

    【讨论】:

    • 最好确保编译器总是看到但并不总是对诊断打印采取行动。 #else 子句应该执行如下操作: #define D(msk, fmt, ...) do { if (0 && (msk & dbgmsk)) printf(fmt, VARARGS); } 而 (0)。 do/while 习惯用法确保您可以在任何可以出现语句的地方使用它; if (0) 意味着代码永远不会被执行,编译器会优化它——但只有在检查它的语法有效性之后。如果将非调试版本定义为空,则不会持续检查调试代码在语法上是否有效。
    【解决方案4】:

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

    请注意,为了简化这一点,您应该将代码中的测试从以下位置更改:

    #if DEBUG
    

    到:

    #ifdef DEBUG
    

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

      • 可能不是正确的方法。使用 Makefile 管理构建模式、DEBUG 或 RELEASE。所以根据构建模式,改变进入 CFLAGS 的内容。这种方法将无缝扩展。
      【解决方案6】:

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

      #ifndef DEBUG
      #define DEBUG 1
      #endif
      

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

      【讨论】:

      • 我会反转默认值 - DEBUG 0 通常,但可以在命令行上覆盖。
      【解决方案7】:

      试试这个。

      在您拥有的第一个文件中:

      #define DEBUG
      

      然后,当您想要调试代码时,请执行以下操作:

      #ifdef DEBUG
      do some stuff
      #endif
      

      这也将阻止您的调试代码将其变为发布代码。

      【讨论】:

      • 我认为你没有理解他的问题。
      【解决方案8】:

      我个人喜欢

      #ifdef 调试 #define IFDEBUG if(0)else #别的 #define IFDBUG if(1)else #万一

      【讨论】:

        猜你喜欢
        • 2020-06-28
        • 2016-05-21
        • 1970-01-01
        • 2010-12-11
        • 1970-01-01
        • 2012-07-09
        • 2015-08-08
        相关资源
        最近更新 更多