c 中的多行宏 (#if-#endif)
Multiline macro in c (#if-#endif)
我的代码:
#define DEBUG 3
#define TEST(...)
#if (DEBUG == 3) \
printf("%s: %s\n", __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: %s\n", __FILE__, __VA_ARGS__);
#else
# define TEST(...)
#endif
int main(void) {
TEST("TEST")
return 0;
}
编辑:虽然像这样的测试型宏很常见,但这不是一个好方法,因为它会在 debug/nondebug 情况下导致不愉快的意外.
在这种情况下会发生什么?
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
不能 "contain" #if
s
我的代码:
#define DEBUG 3
#define TEST(...)
#if (DEBUG == 3) \
printf("%s: %s\n", __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: %s\n", __FILE__, __VA_ARGS__);
#else
# define TEST(...)
#endif
int main(void) {
TEST("TEST")
return 0;
}
编辑:虽然像这样的测试型宏很常见,但这不是一个好方法,因为它会在 debug/nondebug 情况下导致不愉快的意外.
在这种情况下会发生什么?
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
不能 "contain" #if
s