我们可以删除C宏定义中参数周围的括号吗?

Lon*_*ner 3 c macros parentheses c-preprocessor

http://c-faq.com/style/strcmp.html,我学到了以下便利宏:

#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
Run Code Online (Sandbox Code Playgroud)

我想知道为什么在这个宏中使用了这么多括号.每个括号是用于某个目的还是使用冗余括号的宏,这些括号没有用处?

我们可以删除周围的括号s1s2像这样制作一个宏吗?

#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
Run Code Online (Sandbox Code Playgroud)

这个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;
}
Run Code Online (Sandbox Code Playgroud)

上面代码的输出:

1 1
0 0
0 0
Run Code Online (Sandbox Code Playgroud)

你能想象这些宏的使用在哪里Streq可以实现人们所期望的但却MyStreq没有?

Bil*_*nch 14

这是一个相对愚蠢的例子,但确实有不同的结果:

#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.
}
Run Code Online (Sandbox Code Playgroud)


gsg*_*gsg 5

括号有时确实很重要,最好无条件插入括号。考虑以下不良宏:

#define OP(a, b) (a * b) /* BAD */
Run Code Online (Sandbox Code Playgroud)

调用OP(x + 1, y + 1)它会扩展为x + 1 * y + 1,从而打破了预期的分组。括号可防止出现此问题。

如果您在每次使用参数时都用括号括起来的宏定义,那么作者当然会想到这个问题,即使这些paren对于该宏来说是多余的。