When can the parentheses around arguments in macros be omitted?

c, c-preprocessor, macros, parentheses

Solution

It's unsafe to omit if you use any operator that isn't lowest precedence in your expression. I believe that would be comma.

`a op b` where `op` is some operator like `+`, `*` etc. will always bind wrong if `a` contains an expression of low precedence like `1 || 2`.

Note I'm not claiming it's safe in those cases. There are more creative ways to break macros. By the way, don't use macros with side effects in the first place. More generally, don't use macros as functions. (See, e.g., Effective C++).

Problem

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: - The associative priority of assignment symbols is merely higher than comma’s. 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: - DO NOT make macros with side effects! - As for macros with no side effect, just parenthesize all the arguments without second thought! - As for macros with side effect, stop being obsessive! Parenthesize them all! TnT

Original source