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 :
return x*f(x, c);
the output is 3024 (6*7*8*9)
. Why is there a difference in output ? Has it anything to do with the order of evaluation of 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
. 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).