gpt4 book ai didi

c - 什么是具有副作用的表达式?为什么不应将它们传递给宏?

转载 作者:行者123 更新时间:2023-11-30 16:27:08 26 4
gpt4 key购买 nike

我在《C 如何编程》一书中发现了这样一句话:

“具有副作用(即变量值被修改)的表达式不应传递给宏,因为宏参数可能会被多次求值。”。

我的问题是什么是具有副作用的表达式以及为什么不应将它们传递给宏?

最佳答案

经典的例子是计算两个值的最大值的宏:

#define MAX(a, b) ((a) > (b) ? (a) : (b))

现在让我们像这样“调用”宏:

int x = 5;
int y = 7;
int z = MAX(x++, y++);

现在,如果 MAX 是一个普通函数,我们会期望 xy 会递增一次,对吗?然而,因为它是一个宏,所以“调用”被替换为这样:

int z = ((x++) > (y++) ? (x++) : (y++));

如您所见,变量 y 将增加两次,一次在条件中,一次作为 ternary operator 的最终结果。 .

这是具有副作用的表达式(后增量表达式)和宏扩展的结果。

<小时/>

与此相关的是,宏还存在其他危险。例如,让我们采用这个简单的宏:

#define MUL_BY_TWO(x)  (x * 2)

看起来很简单吧?但现在如果我们像这样使用它会怎么样:

int result = MUL_BY_TWO(a + b);

它将像这样扩展

int result = (a + b * 2);

正如您希望知道的那样,乘法的优先级高于加法,因此表达式 a + b * 2 相当于 a + (b * 2),但可能不是宏编写者的意图是什么。这就是为什么宏的参数应该放在自己的括号内:

#define MUL_BY_TWO(x)  ((x) * 2)

那么扩展将是

int result = ((a + b) * 2);

这可能是正确的。

关于c - 什么是具有副作用的表达式?为什么不应将它们传递给宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52839349/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com