3

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?

Palec
  • 12,743
  • 8
  • 69
  • 138
Lone Learner
  • 18,088
  • 20
  • 102
  • 200
  • Related: [The need for parentheses in macros in C](http://stackoverflow.com/q/10820340/2157640) – Palec Apr 29 '15 at 08:52
  • Related: [When can the parentheses around arguments in macros be omitted?](http://stackoverflow.com/q/20964369/2157640) – Palec Apr 29 '15 at 09:44

2 Answers2

15

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.
}
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
6

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.

gsg
  • 9,167
  • 1
  • 21
  • 23