Search code examples
c++functionparametersoperator-precedencesequence-points

Order of Evaluation for passing function arguments - Order of operations for F1( int F2( int& x ), int x )


Okay so I was writing some code earlier. This was the line specifically:

EnterNode( FindNode( terrain_X, terrain_Y, travel_dir ), travel_dir );

I noticed after testing my program something weird was happening. The value being received by the outer function was not the value I was reading when I inspected the stack.

I made an example program: https://ideone.com/wNjJrE

#include <iostream>

int modifyRef(int& A)
{
    A = 0;
    std::cout << "\nint& A = 0";
    return A;
}

void TakeValues(int X, int Y)
{
    std::cout << "\nX = " << X;
    std::cout << "\nY = " << Y;
}

int main()
{
    int Q = 9;
    TakeValues(modifyRef(Q), Q);
    std::cout << std::endl;
    system("pause");
    return 0;
}

This is the output I receive:

int& A = 0
X = 0
Y = 9

I would expect Y to also be 0. How is the order of operations defined for parameter binding to function calls?

(My apologies if I am not using the correct terminology.)


Solution

  • The evaluation order of function arguments is unspecified. When you write:

    TakeValues(modifyRef(Q), Q);
    

    you are relying upon the fact that modifyRef(Q) to be evaluated before Q. But the evaluation order of function arguments is unspecified - it is not necessarily the case that modifyRef(Q) will be sequenced before Q nor vice versa.

    In this case, Q (the second argument) gets evaluated first. So we read 9, and initialize the parameter Y with it. Then we evaluate modifyRef(Q), which zeros out Q and returns it, which leads to initializing X with 0.