c(#if-#endif)中的多行宏

问题描述 投票:0回答:2

我的代码:

#define DEBUG 3
#define TEST(...) 
    #if (DEBUG == 3) \
        printf("%s: %s\n", __FILE__, __VA_ARGS__); 
    #endif 

int main(void) {

    TEST("TEST")

    return 0;
}

错误:在令牌'printf'之前缺少二进制运算符。

我不明白是什么问题

c macros multiline
2个回答
5
投票

您正在尝试将#if放入宏中,但C不允许这种事情。它失败的原因是printf #if]里面的意外。这是一个普通的请求,但只是不允许。

但是,您可以通过更改测试方式来完成同样的事情:

#include <stdio.h>

#define DEBUG 3

#if (DEBUG == 3)
# define TEST(...) printf("%s: %s\n", __FILE__, __VA_ARGS__);
#else
# define TEST(...)
#endif

int main(void) {

   TEST("TEST")

   return 0;
}

EDIT

:尽管像这样的测试类型的宏很常见,但这并不是一个好方法,因为它可能导致在调试/非调试情况下出现令人不快的惊喜。

在这种情况下会发生什么?

   if (something)
       TEST("blah")
   else
       TEST("no")

这在调试模式下可以按预期工作,但由于降级为if (something) else,甚至无法在生产环境中进行编译-甚至没有结束分号。很容易找到其他更狡猾的示例。

在这样的宏中隐藏分号通常会带来麻烦,因此更好的方法是使它们像您必须自己提供分号的功能一样,最明显的方法是:]

#  #define TEST(...) printf("%s: %s\n", __FILE__, __VA_ARGS__) // no semicolon

...
    if (something)
        TEST("blah");
    else
        TEST("no");

这是更好的方法,并且不会引起什么意外,但是仍然有些麻烦,因为它可能会留下一些悬挂的分号,有些编译器反对。

此修补程序可以是:

#if (DEBUG == 3)
# define TEST(...) printf("%s: %s\n", __FILE__, __VA_ARGS__)
#else
# define TEST(...) ((void)0)  // dummy statement
#endif

至少可以使编译器安静。这里也有其他方法。

在C中#define不能“包含”#ifs


0
投票

在C中#define不能“包含”#ifs

© www.soinside.com 2019 - 2024. All rights reserved.