【问题标题】:Using macro statement in macro function in C在 C 中的宏函数中使用宏语句
【发布时间】:2021-12-23 18:10:55
【问题描述】:

使用#ifdef <macro> <statement> #endif 允许仅在开发期间显示详细消息,并且非常方便。我想知道类似下面的代码是否可能,变得更短:

// pseudo-code:

#define IN_DEV
#define DEBUG_ONLY(statement) (#ifdef IN_DEV (statement) #endif)

int main(void)
{
   DEBUG_ONLY(printf("hello from debug mode\n");)
   //...
}

这只会花费我一个可读性很强的可以打开或关闭的单行。像这样/接近这样的事情可能吗?

【问题讨论】:

    标签: c macros c-preprocessor


    【解决方案1】:

    将整个表达式作为参数传递给宏没有多大意义。这既危险又不可维护。更糟糕的是,它让我们走上了“让我们发明自己的私有宏语言,而不是使用任何人都能理解的可读 C”的混淆道路。即使出于调试目的,这也是一个糟糕的想法。

    更明智的方法是使用类似函数的打印宏,它只在调试版本中打印一些内容。

    #ifdef INDEV
      #define DEBUG_PRINT(...) printf(__VA_ARGS__)
    #else
      #define DEBUG_PRINT(...)
    #endif
    
    int main(void)
    {
       DEBUG_PRINT("hello from debug mode\n");
    }
    

    可以选择将此宏缩小为仅接受字符串并使其更安全(仅限 C17):

    #ifdef INDEV
      #define DEBUG_PRINT(str) _Generic((str), char*: puts(str))
    #else
      #define DEBUG_PRINT(str) _Generic((str), char*: (void)0)
    #endif
    

    【讨论】:

      【解决方案2】:

      您可以更改 DEBUG_ONLY 的含义,具体取决于是否定义了 IN_DEV

      // pseudo-code:
      
      #ifdef IN_DEV
      #define DEBUG_ONLY(statement) {statement}
      #else
      #define DEBUG_ONLY(statement) // Nothing
      #endif
      
      int main(void)
      {
         DEBUG_ONLY(printf("hello from debug mode\n");)
         //...
      }
      
      

      运行示例:Link

      【讨论】:

      • 非常聪明,谢谢!
      【解决方案3】:

      这是不可能的。您不能在宏定义中使用#if

      你可以这样做:

      #define IN_DEV
      
      #ifdef
       #define DEBUG_ONLY(statement) (statement)
      #else
       #define DEBUG_ONLY(statement)
      #endif
      
      int main(void)
      {
         DEBUG_ONLY(printf("hello from debug mode\n");)
         //...
      }
      

      这也可以仅使用单个宏 IN_DEV 进行切换。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多