什么时候可以省略宏中参数周围的括号? [英] When can the parentheses around arguments in macros be omitted?

查看:15
本文介绍了什么时候可以省略宏中参数周围的括号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常并且经常觉得宏定义中的一些围绕参数的括号是多余的.把所有东西都括起来太不方便了.如果我可以保证参数不需要括号,我可以省略括号吗?还是强烈推荐将它们都括起来?

我在写的时候想到了这个问题:

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

我认为如果一个参数作为左值出现在宏中,括号可以省略,因为这意味着参数出现时没有其他操作.

我的理由是:

  1. 赋值符号的关联优先级仅高于逗号.
  2. 你不能让编译器误以为你的参数是一个带有逗号的表达式.例如 SWAP(a, b, b) 不会被成功解释为

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

    可以通过编译.

我说的对吗?谁能给我一个反例?

在下面的例子中,

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

我认为参数 a 不需要用括号括起来.在这种特定情况下,也不需要参数 b,对吧?

@JaredPar:

<块引用>

 #include <stdio.h>#define ADD(a, b) (a += (b))诠释主要(){int a = 0, b = 1;添加(a;b,2);返回0;}

这在我的 VS2010 上无法编译成功.错误 C2143:语法错误:在 ';' 之前缺少 ')'


简而言之,您不需要将在宏中作为左值出现的参数括起来,但强烈建议您将它们全部括起来.

宏规则:

  1. 不要制作有副作用的宏!
  2. 至于没有副作用的宏,把所有参数都加括号就行了!
  3. 至于有副作用的宏,别再执着了!把它们都括起来!TnT

解决方案

如果在表达式中使用任何不是最低优先级的运算符,则省略是不安全的.我相信那是逗号.

a op b 其中 op 是一些运算符,如 +* 等,如果a 包含一个低优先级的表达式,例如 1 ||2.

请注意,我声称在这些情况下它是安全的.有更多创造性的方法来打破宏.顺便说一句,首先不要使用具有副作用的宏.更一般地说,不要将宏用作函数.(参见,例如,Effective C++).

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

解决方案

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++).

这篇关于什么时候可以省略宏中参数周围的括号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆