什么是具有副作用的表达式,为什么不应该将它们传递给宏? [英] What are expressions with side effects and why should they be not passed to a macro?

查看:5
本文介绍了什么是具有副作用的表达式,为什么不应该将它们传递给宏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 C How to Program 一文中看到了一个语句:

I came across a statement in the text C How to Program:

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

"Expressions with side effects (i.e., variable values are modified) should not be passed to a macro because macro arguments may be evaluated more than once.".

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

My question is what are expressions with side effects and why should they be not passed to a macro?

推荐答案

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

The classic example is a macro to calculate the maximum of two value:

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

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

Now lets "call" the macro like this:

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

现在如果 MAX 是一个普通函数,我们希望 xy 会增加一次,对吗?然而,因为它是一个宏,所以调用"被替换如下:

Now if MAX was a normal function, we would expect that x and y would be incremented once, right? However because it's a macro the "call" is replaced like this:

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

如您所见,变量 y 将增加 两次,一次在条件中,一次作为 三元运算符.

As you see, the variable y will be incremented twice, once in the condition and once as the end-result of the ternary operator.

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

This is the result of an expression with side-effects (the post-increment expression) and a macro expansion.

在相关说明中,宏还存在其他危险.例如,让我们使用这个简单的宏:

On a related note, there are also other dangers with macros. For example lets take this simple macro:

#define MUL_BY_TWO(x)  (x * 2)

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

Looks simple right? But now what if we use it like this:

int result = MUL_BY_TWO(a + b);

这会像这样扩展

int result = (a + b * 2);

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

And as you hopefully knows multiplication have higher precedence than addition, so the expression a + b * 2 is equivalent to a + (b * 2), probably not what was intended by the macro writer. That is why arguments to macros should be put inside their own parentheses:

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

那么展开就是

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

这可能是正确的.

这篇关于什么是具有副作用的表达式,为什么不应该将它们传递给宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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