【问题标题】:Parenthesis in define macros定义宏中的括号
【发布时间】:2016-02-10 16:45:23
【问题描述】:

什么时候需要将定义宏的整个(右)表达式放在括号中?

如果我这样做

#define SUM(x, y) ((x)+(y))

我必须将正确的表达式放在括号中,因为“+”在 C 语言中的优先级较低(如果我在以下上下文中使用它就行不通SUM(x, y) * 5U

如果我使用最高优先级的运算符,这些括号是否仍然需要,例如

#define F foo()

甚至

#define ACCESS(x, y) (x)->(y)

是否存在会像 SUM() 示例那样破坏实际含义的表达式?)

对于我使用http://en.cppreference.com/w/c/language/operator_precedence的优先规则

【问题讨论】:

  • 我不知道必要,但我仍然称其为良好做法。如果有人(比如说)向F 宏添加一个校正因子以(无论如何)规范化foo 的输出,但忘记添加括号怎么办?您将花费大量时间试图找出问题所在。
  • 另外值得注意的是,您引用的优先级表实际上并不是语言标准,而是标准中更复杂规则的更易于使用的表示.我不是 C 专家或语言律师,但这些规则可能会改变一些事情。

标签: c macros


【解决方案1】:

使用括号来避免一些大错误是一个很好的做法。目前,您可能认为您的运算符具有高优先级,但假设您正在制作代码的头文件并将其提供给使用该文件中的宏且函数具有更高优先级的朋友,因此届时它将是调试代码非常痛苦。作为程序员,您可以通过添加括号来节省这段时间。

【讨论】:

  • 我的问题是什么时候有必要在宏周围加上括号。当然,如果运算符的优先级较低,例如“+” 则始终需要括号(如 SUM 示例中)。但是像“->”、“++”、“[]”、“.”这样具有高优先级的表达式呢? ?
  • 我想我找到了一个很好的例子,它说明了为什么“使用括号来避免一些大错误是一种很好的做法。”并不总是正确的!想象一下你有一个#define foo() 并且foo 被定义为do{ } while(0) 那么这将不再编译!
【解决方案2】:

一些使用简单#defines的程序员会写

#define ZERO (0)

除了把事情复杂化之外没有任何用处。

实际上,宏是所见即所得的,因此考虑到这一点,您可以决定需要哪些括号:

SUM(3,4) => ((3)+(4))    // parentheses around 3 and 4 are not necessary

RATIO(3+4,4+5) => ((3+4)/(4+5))    // probably necessary here due to operator precedence

解决这个问题不是火箭科学,实际上很简单。

【讨论】:

  • 我认为这并不能回答我的问题,您只是解释了如何在 C 中评估宏。
  • 是的,这就是我刚刚所做的。您是否认为宏中括号的计算方式与其他 C 语句中的不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-05
  • 2018-11-11
  • 2021-01-17
  • 1970-01-01
  • 2019-10-21
  • 2021-12-31
  • 1970-01-01
相关资源
最近更新 更多