Search code examples
c++referenceoperator-precedence

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 :

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 ?


Solution

  • 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).