简体   繁体   English

运营商评估顺序*

[英]Evaluation order of Operator *

I have the following piece of code : 我有以下代码:

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

Now, suppose I call the above function like this : 现在,假设我像这样调用上述函数:

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

The output is 9^4 , since x is passed by reference, hence the final value of x should be 9, but when the return statement of the above function is changed to : 输出为9^4 ,因为x是通过引用传递的,因此x的最终值应为9,但是当上述函数的return语句更改为时:

return x*f(x, c);

the output is 3024 (6*7*8*9) . 输出为3024 (6*7*8*9) Why is there a difference in output ? 为什么输出会有所不同? Has it anything to do with the order of evaluation of Operator* ? Operator*的评估顺序有关吗? If we are asked to predict the output of the above piece of code, is it fixed, compiler-dependent or unspecified ? 如果要求我们预测以上代码的输出,它是固定的,依赖于编译器的还是未指定的?

When you write: 当你写:

f(x,c)*x

the compiler may choose to retrieve the stored value in x (for the second operand) either before or after calling f . 编译器可以选择在调用f之前或之后检索x的存储值(用于第二个操作数)。 So there are many possible ways that execution could proceed. 因此,执行的方式有很多种。 The compiler does not have to use any consistency in this choice. 编译器在此选择中不必使用任何一致性。

To avoid the problem you could write: 为了避免该问题,您可以编写:

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

Note: It is unspecified behaviour; 注意:这是未指定的行为; not undefined behaviour because there is a sequence point before and after any function call (or in C++11 terminology, statements within a function are indeterminately-sequenced with respect to the calling code, not unsequenced). 不是不确定的行为,因为在任何函数调用之前和之后都有一个序列点(或在C ++ 11术语中,函数中的语句相对于调用代码不确定地排序,而不是未排序)。

The cause is that f() function has side effect on its x parameter. 原因是f()函数对其x参数有副作用。 The variable passed to this parameter is incremented by the value of the second parameter c when the function returns. 函数返回时,传递给该参数的变量将增加第二个参数c的值。

Therefore when you swap the order of the operand, you get different results as x contains different values before and after the function is called. 因此,当交换操作数的顺序时,您会得到不同的结果,因为在调用函数之前和之后x包含不同的值。

However, note that behaviour of the code written in such way is undefined as compiler is free to swap evaluation of operand in any order. 但是,请注意,未定义以这种方式编写的代码的行为,因为编译器可以任意顺序交换操作数的求值。 So it can behave differently on different platforms, compilers or even with different optimization settings. 因此,它在不同的平台,编译器甚至在不同的优化设置下都可能表现不同。 Because of that it's generally necessary to avoid such side effects. 因此,通常有必要避免此类副作用。 For details see http://en.cppreference.com/w/c/language/eval_order 有关详细信息,请参见http://en.cppreference.com/w/c/language/eval_order

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

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