Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When can the parentheses around arguments in macros be omitted?

Often and often I felt some of the parentheses around arguments in macro definitions were redundant. It’s too inconvenient to parenthesize everything. If I can guarantee the argument needs not be parenthesized, can I omit the parentheses? Or is parenthesizing them all highly recommended?

I came up with this question when I wrote:

#define SWAP_REAL(a, b, temp) do{double temp = a; a = b; b= temp;}while(0)

I think that if an argument appears as an l-value in the macro, the parentheses can be omitted because that means the argument appears with no other operation.

My reasoning is:

  1. The associative priority of assignment symbols is merely higher than comma’s.
  2. You cannot confuse the compiler into thinking that your argument is an expression with a comma in it. For example, SWAP(a, b, b) will not be interpreted successfully as

    do{double temp = a, b; a, b = b; b= temp;}while(0)
    

    which can pass compilation.

Am I right? Can anyone give me a counter-example?

In the following example,

#define ADD(a, b) (a += (b))

I think the argument a needn’t be parenthesized. And in this specific case, neither needs the argument b, right?

@JaredPar:

   #include <stdio.h>
   #define ADD(a, b) (a += (b))
   int main(){
      int a = 0, b = 1;
      ADD(a; b, 2);
      return 0;
   }

This cannot be compiled successfully on my VS2010. Error C2143: syntax error : missing ')' before ';'


In a nutshell, you don’t need to parenthesize the arguments having appeared as an l-value in the macro, but you are highly recommended to parenthesize them all.

Rules of Macros:

  1. DO NOT make macros with side effects!
  2. As for macros with no side effect, just parenthesize all the arguments without second thought!
  3. As for macros with side effect, stop being obsessive! Parenthesize them all! TnT
like image 987
lzl124631x Avatar asked Jan 11 '23 12:01

lzl124631x


1 Answers

Here is one case where it makes a demonstrable difference

ADD(x;y, 42)

With parens this leads to a compilation error but without it leads to code that compiles.

(x;y) += 42; // With parens errors
x;y += 42;   // Without parens compiles

This may look like a silly example but it's possible combining macros together can easily lead to strange code expressions like the above.

Why take the chance here? It's just 2 characters

like image 71
JaredPar Avatar answered Jan 25 '23 05:01

JaredPar