[英]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.