【发布时间】:2014-01-24 16:58:10
【问题描述】:
我经常并且经常觉得宏定义中的一些围绕参数的括号是多余的。把所有东西都括起来太不方便了。如果我可以保证参数不需要括号,我可以省略括号吗?还是强烈推荐将它们都括起来?
我在写的时候想到了这个问题:
#define SWAP_REAL(a, b, temp) do{double temp = a; a = b; b= temp;}while(0)
我认为如果一个参数作为左值出现在宏中,括号可以省略,因为这意味着参数出现时没有其他操作。
我的理由是:
- 赋值符号的关联优先级仅高于逗号。
-
您不能让编译器误以为您的参数是一个带有逗号的表达式。例如,
SWAP(a, b, b)不会被成功解释为do{double temp = a, b; a, b = b; b= temp;}while(0)可以通过编译。
我说的对吗?谁能给我一个反例?
在下面的例子中,
#define ADD(a, b) (a += (b))
我认为参数a 不需要加括号。而且在这种特定情况下,也不需要参数b,对吧?
@JaredPar:
#include <stdio.h> #define ADD(a, b) (a += (b)) int main(){ int a = 0, b = 1; ADD(a; b, 2); return 0; }
这在我的 VS2010 上无法编译成功。 Error C2143: syntax error : missing ')' before ';'
简而言之,您不需要将在宏中作为左值出现的参数括起来,但强烈建议您将它们全部括起来。
宏规则:
- 不要制作有副作用的宏!
- 至于没有副作用的宏,把所有的参数都加括号就行了!
- 至于有副作用的宏,别再执着了!把它们都括起来! TnT
【问题讨论】:
-
如果您需要使用未完全括起来的宏,您将花费多少时间来确定它是否在所有情况下都安全?
-
@KeithThompson 相反,如果您不知道需要用括号括起来的内容,您怎么知道自己正确编写了宏?
-
或许可以考虑相反的问题——人们可能会写出的宏实际上会被防御性括号破坏?
-
我只是讨厌用括号括起来怀疑变量的必要性的感觉。
-
我不确定你认为你用 MIN 演示了什么......我说过如果你省略参数周围的括号,事情将无法正常工作,并且你的测试出现错误 C2106证实了这一点。如果您使用带括号的宏参数,则不会有问题。所以,AFAICT,你同意我所说的。
标签: c macros c-preprocessor parentheses