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

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

问题描述

我在C语言如何编程中遇到一个声明:

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会被递增一次,对吗?但是,因为它是一个宏,所以"call"被替换为:

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天全站免登陆