我们可以删除 C 宏定义中参数周围的括号吗?
Can we remove parentheses around arguments in C macros definitions?
从http://c-faq.com/style/strcmp.html,我学到了以下方便的宏:
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
我想知道为什么这个宏中使用了这么多括号。每个圆括号是否都有用,或者这个宏是否使用了毫无意义的冗余圆括号?
我们可以删除 s1
和 s2
周围的括号并制作这样的宏吗?
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
MyStreq
宏对我来说似乎和 Streq
一样好用。
#include <string.h>
#include <stdio.h>
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
int main()
{
printf("%d %d\n", Streq("foo", "foo"), MyStreq("foo", "foo"));
printf("%d %d\n", Streq("fox", "foo"), MyStreq("fox", "foo"));
printf("%d %d\n", Streq("foo", "fox"), MyStreq("foo", "fox"));
return 0;
}
以上代码的输出:
1 1
0 0
0 0
您能想象这些宏的任何用法,其中 Streq
可以达到人们预期的效果,而 MyStreq
却没有?
括号有时很重要,无条件插入括号是个好主意。考虑以下糟糕的宏:
#define OP(a, b) (a * b) /* BAD */
调用为 OP(x + 1, y + 1)
它将扩展为 x + 1 * y + 1,打破了预期的分组。括号可以防止这个问题。
如果您阅读每个参数使用都带有括号的宏定义,那么作者肯定会考虑到这个问题 - 即使这些括号恰好对于该宏来说是多余的。
这是一个相对愚蠢的例子,但它确实有不同的结果:
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
#define s1 "foo", "blah"
int main() {
Streq(s1, "blah"); // Compiles and compares equal.
MyStreq(s1, "blah"); // Compiler error. Too many parameters.
}
从http://c-faq.com/style/strcmp.html,我学到了以下方便的宏:
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
我想知道为什么这个宏中使用了这么多括号。每个圆括号是否都有用,或者这个宏是否使用了毫无意义的冗余圆括号?
我们可以删除 s1
和 s2
周围的括号并制作这样的宏吗?
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
MyStreq
宏对我来说似乎和 Streq
一样好用。
#include <string.h>
#include <stdio.h>
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
int main()
{
printf("%d %d\n", Streq("foo", "foo"), MyStreq("foo", "foo"));
printf("%d %d\n", Streq("fox", "foo"), MyStreq("fox", "foo"));
printf("%d %d\n", Streq("foo", "fox"), MyStreq("foo", "fox"));
return 0;
}
以上代码的输出:
1 1
0 0
0 0
您能想象这些宏的任何用法,其中 Streq
可以达到人们预期的效果,而 MyStreq
却没有?
括号有时很重要,无条件插入括号是个好主意。考虑以下糟糕的宏:
#define OP(a, b) (a * b) /* BAD */
调用为 OP(x + 1, y + 1)
它将扩展为 x + 1 * y + 1,打破了预期的分组。括号可以防止这个问题。
如果您阅读每个参数使用都带有括号的宏定义,那么作者肯定会考虑到这个问题 - 即使这些括号恰好对于该宏来说是多余的。
这是一个相对愚蠢的例子,但它确实有不同的结果:
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
#define s1 "foo", "blah"
int main() {
Streq(s1, "blah"); // Compiles and compares equal.
MyStreq(s1, "blah"); // Compiler error. Too many parameters.
}