Try changing the signature of your functions:
int ModifyRef( int& A );
void TakeValues( int X, int Y );
to the following...
int& ModifyRef( int& A );
void TakeValues( int& X, int& Y );
and see what your output will be in main when you call this line of code:
int q = 9;
TakeValues( ModifyRef(q), q );
then reverse the order of the parameters as such
TakeValues( q, ModifyRef(q) );
and compare the results.
When I did this on my machine Win 7 64bit with VS2015 Community on an Intel Core2 Quad Extreme the results I was given for both situations when using references were the same and the output I am getting is:
I changed the value of A
in ModifyRef()
from 0 to 7 for testing purposes.
int& A = 7
X = 7
Y = 7
for both situations where either the inner function is the first parameter and the stand alone variable is the second or the inner function is the second parameter with the stand alone variable as the first.
Since I am receiving the same results it appears to me that do to how the compiler creates and handles the stack pointer the ModifyRef()
appears to be evaluated first and once that function is finished since q
is now being referenced instead of being a stack copy it is being overwritten by whatever value it is being set to within the ModifyRef function.
I also modified your ModifyRef()
function slightly so that I can see what its passed in parameter is instead of having a number hard coded into its print out statement.
int& ModifyRef( int& A ) {
A = 7; // Changed Value From 0 To 7 For Testing Purposes
std::cout << "n\int& A = " << A;
return A;
}
However this effect may only apply when using only references.
When I revert back to your original function signatures and I call it in this order:
q = 9;
TakeValues( ModifyRef( q ), q );
As is your original code was presented the output I am getting is:
int& A = 7
X = 7
Y = 9
However when I reverse the parameters to:
q = 9;
TakeValues( q, ModifyRef( q ) );
My output is:
int& A = 7
X = 7
Y = 7
So what I am seeing in these two situations is slightly different.
In the first order of parameters, Y
or the second parameter is being set to 9 as q
is initialized to 9 and Y
within TakeValues()
is printing out a stack copy with a value of 9. Then X
is being valuated by ModifyRef()
where q
has a value of 9 but then it is being modified since it is a reference so when TakeValues()
sets X
from q
, q
was already changed from 9 to 7 so X
is now being set to 7.
In the second order of parameters it appears that ModifyRef()
is being called first and changes q
from 9 to 7 so TakeValues()
is setting Y
to 7 and since this function is using a reference q
was also changed from 9 to 7, so when the first parameter is taking q
to set X
q
was already changed from 9 to 7.
I do not know if this is compiler dependent but at least on my machine it appears that the call stack for the parameters is happening from farthest right to left. This also makes sense when you think about it due to when functions have default values.
Example:
class foo {
void bar( int a, int b, int c = 3 ) {
std::cout << a << ", " << b << ", " << c << std::endl;
}
};
All default values in a function declaration must be to the far right for you can not have:
class foo {
void bar( int a = 1, int b, int c ) { ... } // Compile Error
};
I hope this helps to clarify what is going on within your code when you begin to call a function within a function as a parameter either if you are using passing by value(stack copy) or by reference.