【问题标题】:C++ define expression evaluation [duplicate]C ++定义表达式评估[重复]
【发布时间】:2016-05-04 12:28:24
【问题描述】:

假设我们有这个表达式:

#define cube(x) x * x * x

然后我们称之为:

int n = 3, v;
v = cube(n + 1);   // v = 10
v = cube((n + 1)); // v = 64
v = cube(n);       // v = 27

那么问题来了:为什么第一次操作不做v = 64

【问题讨论】:

  • 阅读运算符优先级。手动展开 MACRO 并检查。
  • 这必须是重复的...
  • @chqrlie 我怀疑是这样,但我找不到类似的东西。
  • 这里是one。当然它谈到了 C++,因为你有替换宏的机制。但陷阱是一样的。

标签: c++


【解决方案1】:

宏不被求值(就求值的一般解释而言),它们在编译时被扩展。

在编译文件之前,还有另一个名为 C Preprocessor 的程序替换宏调用 literally/textually 并为实际编译准备文件,因此你的宏

#define cube(x) x * x * x when you do this

这个

v = cube(n + 1);

被替换为这个(扩展是正确的术语

v = n + 1 * n + 1 * n + 1;
// Simplifies to
v = n + n + n + 1;
// and again
v = 3 * n + 1;

which for n = 3 给你10 正是观察到的结果。

注意,当你添加括号时

v = cube((n + 1));

那么,展开是

v = (n + 1) * (n + 1) * (n + 1);

这是你期望cube() 做的事情,所以为了防止这种情况,你应该像这样重新定义你的宏

#define cube(x) ((x) * (x) * (x))

如果你正在使用 gcc 试试

gcc -E source.c

并检查结果以验证宏是如何展开的。

【讨论】:

  • @iharob:很好的答案。您可以添加有关多重评估潜在问题的警告。
  • @tomab,这是纯文本替换,如果您尝试使用具有副作用的东西扩展宏,这会让您更加惊讶。
  • 只是一个挑剔:宏/文本扩展一种评估形式,尽管它不是大多数人正在考虑的形式(而且,重要的是,它不是根据C++ 的规则,也不是传统代数的规则)。
猜你喜欢
  • 1970-01-01
  • 2017-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-08
  • 2010-10-22
  • 2015-06-26
  • 1970-01-01
相关资源
最近更新 更多