Can we remove parentheses around arguments in C ma

2019-01-28 11:36发布

From http://c-faq.com/style/strcmp.html, I learned the following convenience macro:

#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)

I want to know why there are so many parentheses being used in this macro. Is each parenthesis serving a purpose or is this macro using redundant parentheses that serve no purpose?

Can we remove the parentheses around s1 and s2 and make a macro like this?

#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)

The MyStreq macro seems to work for me as nicely as 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;
}

Output from the code above:

1 1
0 0
0 0

Can you imagine any usage of these macros where Streq does what one would expect but MyStreq does not?

2条回答
Deceive 欺骗
2楼-- · 2019-01-28 12:28

Parentheses do sometimes matter, and it is a good idea to unconditionally insert them. Consider the following poor macro:

#define OP(a, b) (a * b) /* BAD */

Invoked as OP(x + 1, y + 1) it will expand to x + 1 * y + 1, breaking the intended grouping. Parentheses prevent this problem.

If you read a macro definition with parentheses around each argument use, the author certainly had this issue in mind - even if those parens happen to be redundant for that macro.

查看更多
别忘想泡老子
3楼-- · 2019-01-28 12:39

Here's a relatively dumb example, but it does have a different result:

#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.
}
查看更多
登录 后发表回答