【问题标题】:Debug Print Macro in C?在 C 中调试打印宏?
【发布时间】:2023-03-13 11:02:01
【问题描述】:

在 C 中,定义一个类似 printf 的宏的正确方法是什么,该宏仅在定义了 DEBUG 符号时才打印?

#ifdef DEBUG
#define DEBUG_PRINT(???) ???
#else
#define DEBUG_PRINT(???) ???
#endif

在哪里???是我不知道该填什么的地方

【问题讨论】:

标签: c macros


【解决方案1】:

这个成语我见多了:

#ifdef DEBUG
# define DEBUG_PRINT(x) printf x
#else
# define DEBUG_PRINT(x) do {} while (0)
#endif

像这样使用它:

DEBUG_PRINT(("var1: %d; var2: %d; str: %s\n", var1, var2, str));

额外的括号是必需的,因为一些较旧的 C 编译器不支持宏中的 var-args。

【讨论】:

  • 感谢您对额外括号的注释。
  • 我在您的实现中发现了一些小错误(例如,x 周围缺少括号,并且没有使用__VA_ARGS__)。 So, here is my approach, based on yours.
  • @GabrielStaples 这个答案旨在解释非常古老的代码,早于基于__VA_ARGS__ 的方法。在不到 20 年的代码中,您当然应该更喜欢 __VA_ARGS__
【解决方案2】:
#ifdef DEBUG
#define DEBUG_PRINT(...) do{ fprintf( stderr, __VA_ARGS__ ); } while( false )
#else
#define DEBUG_PRINT(...) do{ } while ( false )
#endif

【讨论】:

  • +1 表示__VA_ARGS__,但请注意,这仅需要存在于 C99 实现中。
  • 其实,fprintf() 周围不需要do { ... } while (0) 成语
【解决方案3】:

类似:

#ifdef DEBUG
#define DEBUG_PRINT(fmt, args...)    fprintf(stderr, fmt, ## args)
#else
#define DEBUG_PRINT(fmt, args...)    /* Don't do anything in release builds */
#endif

【讨论】:

    【解决方案4】:

    谢谢 mipadi,我也用文件信息改进了你的 DEBUG_PRINT。

    #define DEBUG 3
    
    #if defined(DEBUG) && DEBUG > 0
     #define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
        __FILE__, __LINE__, __func__, ##args)
    #else
     #define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
    #endif
    

    用最新的clang测试,例如

    int main(int argc, char **args) {
        DEBUG_PRINT("Debugging is enabled.\n");    
        DEBUG_PRINT("Debug level: %d", (int) DEBUG);
    }
    

    输出:

    DEBUG: debug.c:13:main(): Debugging is enabled.
    DEBUG: debug.c:14:main(): Debug level: 3
    

    【讨论】:

      【解决方案5】:

      使用不同的 DEBUG_PRINT 签名,它们不必相同,例如:

      #ifdef DEBUG
      #define DEBUG_PRINT printf
      #else
      #define DEBUG_PRINT(...)
      #endif
      

      这样在调试模式下,DEBUG_PRINT 调用将被 printf 替换。发布时它将忽略以前使用的所有参数。

      希望对你有帮助。

      【讨论】:

        【解决方案6】:

        你可以简单地使用:

        #ifdef DEBUG
            #define DEBUG_PRINT printf
        #else
            #define DEBUG_PRINT
        #endif
        

        【讨论】:

        • 如果你有类似if(x) DEBUG_PRINT("SOME DEBUG"); 这样的代码,那么这不起作用。
        【解决方案7】:

        我最喜欢这种方式,因为它不会在您的发布版本中添加任何 asm 指令。

        #define DEBUG
        #ifdef DEBUG
        #define  debug_printf(fmt, ...)  printf(fmt, __VA_ARGS__);
        #else
        #define debug_printf(fmt, ...)    /* Do nothing */
        #endif
        

        【讨论】:

          【解决方案8】:

          我在this implementation 中看到了一些小错误。所以,这是我的方法:

          #ifdef DEBUG
              #define DEBUG_PRINTF(...) printf("DEBUG: "__VA_ARGS__)
          #else
              #define DEBUG_PRINTF(...) do {} while (0)
          #endif
          

          示例用法:

          DEBUG_PRINTF("hello\n");
          

          然后,如果我在 C 构建选项中使用 -DDEBUG 定义进行构建和运行,如下所示:

          # Build
          gcc -Wall -Wextra -Werror -std=c11 -DDEBUG -o build/my_program \
          my_program_tests.c my_program.c
          
          # Run
          build/my_program
          

          然后我看到这个输出:

          DEBUG: hello
          

          但是,如果我在编译器 C 选项中不使用 -DDEBUG 定义进行构建,那么我将看不到任何调试打印。

          【讨论】:

            猜你喜欢
            • 2010-12-11
            • 1970-01-01
            • 1970-01-01
            • 2012-10-15
            • 2011-11-05
            • 1970-01-01
            • 2012-12-24
            相关资源
            最近更新 更多