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



my code:

#define DEBUG 3
#define TEST(...) 
#if (DEBUG == 3) 
printf("%s: %sn", __FILE__, __VA_ARGS__); 
#endif 
int main(void) {
TEST("TEST")
return 0;
}

错误:在标记"printf"之前缺少二进制运算符。

我不明白有什么问题

您试图将#if放在宏中,但 C 不允许这种事情。 它失败的原因是#if 内部printf出乎意料。 这是一个常见的请求,但只是不允许。

但是,您可以通过更改测试方式来完成相同的操作:

#include <stdio.h>
#define DEBUG 3
#if (DEBUG == 3)
# define TEST(...) printf("%s: %sn", __FILE__, __VA_ARGS__);
#else
# define TEST(...)
#endif
int main(void) {
TEST("TEST")
return 0;
}

编辑:虽然像这样的测试类型宏很常见,但这不是一个好方法,因为它可能会导致调试/非调试情况下的不愉快意外。

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

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

这在调试模式下按预期工作,但甚至不会在生产环境中编译,因为它会转移到if (something) else- 它甚至没有右分号。很容易找到其他更狡猾的例子。

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

#  #define TEST(...) printf("%s: %sn", __FILE__, __VA_ARGS__) // no semicolon
...
if (something)
TEST("blah");
else
TEST("no");

这更好,导致更少的意外,但它仍然有点麻烦,因为它可能会留下一个悬而未决的分号,这是一些编译器反对的。

解决此问题的方法可以是:

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

这至少使编译器安静下来。 这里还有其他方法。

在 C 语言中,#define不能"包含"#if

最新更新