繁体   English   中英

运营商评估顺序*

[英]Evaluation order of Operator *

我有以下代码:

int f(int &x, int c){
    c = c - 1;
    if (c == 0) return 1;
    x = x + 1;
    return f(x, c)*x;
}

现在,假设我像这样调用上述函数:

int p = 5;
std::cout << f(p, p) << std::endl;

输出为9^4 ,因为x是通过引用传递的,因此x的最终值应为9,但是当上述函数的return语句更改为时:

return x*f(x, c);

输出为3024 (6*7*8*9) 为什么输出会有所不同? Operator*的评估顺序有关吗? 如果要求我们预测以上代码的输出,它是固定的,依赖于编译器的还是未指定的?

当你写:

f(x,c)*x

编译器可以选择在调用f之前或之后检索x的存储值(用于第二个操作数)。 因此,执行的方式有很多种。 编译器在此选择中不必使用任何一致性。

为了避免该问题,您可以编写:

auto x_temp = x;
return f(x, c) * x_temp;

注意:这是未指定的行为; 不是不确定的行为,因为在任何函数调用之前和之后都有一个序列点(或在C ++ 11术语中,函数中的语句相对于调用代码不确定地排序,而不是未排序)。

原因是f()函数对其x参数有副作用。 函数返回时,传递给该参数的变量将增加第二个参数c的值。

因此,当交换操作数的顺序时,您会得到不同的结果,因为在调用函数之前和之后x包含不同的值。

但是,请注意,未定义以这种方式编写的代码的行为,因为编译器可以任意顺序交换操作数的求值。 因此,它在不同的平台,编译器甚至在不同的优化设置下都可能表现不同。 因此,通常有必要避免此类副作用。 有关详细信息,请参见http://en.cppreference.com/w/c/language/eval_order

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM