Tuesday, March 23, 2010

Call-By-Value/Call-By-Reference

How many times do programmers, from the fledgling novice to the expert, face the question of Call-By-Value/Call-By-Reference? This question comes in the form of someone wanting to better understand, in the form of deciding which to use in a particular programming, or in the form of the default method of parameter passing for a particular language.

Now, tonight I really have no desire to compare languages and their particualar method(s) of parameter passing. What I plan to do here is extend an answer that I recently passed onto someone else. So what follows is just a 'copy and paste' of an email I sent earlier...so I hope I didn't mistype anything! :-)

--from email--

Call-by-value and call-by-reference can be a little confusing, especially when you consider that they are implemented differently in different languages. One note of caution before going further is that in some languages, passing a pointer is still "technically" a call-by-value parameter until you actually deference it in the function; likewise, passing of the actual address ( &addOfMyVar ) is the actual address until you reference it's value. So the caution here is that, when working with pointers, be careful to deference/reference as needed. Not taking care of this could/would produce undefined/undesired results or errors.


Generally, I can't think of a normal situation where you would explicitly return by reference. To export data from a subprogram/function/etc, you would normally do one of two things:
Assign a variable the value of the return:
- someVar = myFunction(int x, int y, int z);
of, you would pass-by-reference those variables that you need changed in the caller's scope to the submodule
- myFunction (int x as ref, int y as ref, int z as ref);


That all said:
Given the below example, the full output should be expected to be:
3 2 1 // first write of submodule
4 5 6 // second write of submodule
6 2 3 // final write of main, after submodule has returned.

Example:

Main
Declare X, Y, Z As Integer
Set X = 1
Set Y = 2
Set Z = 3
Call Display (Z, Y, X)
Write X + " " + Y + " " + Z End Program
Subprogram Display ( Integer Num1, Integer Num2, Integer Num3 As Ref)
Write Num1 + " " + Num2 + " " + Num3
Set Num1 = 4
Set Num2 = 5
Set Num3 = 6
Write Num1 + " " + Num2 + " " + Num3
End Subprogram

Output Explained:
The reason for this:
- 3 2 1 // line 1 of output
- You are calling Display(3, 2, 1)
- The subprogram will first display these values as they are passed.
- 3 and 2 are both copies, and that is what is being displayed, the local (scoped to the subprogram) copy of num1('Z') and num2('Y').
- 1 is being passed as a reference, so num3 will 'basically' be the same address location (and value, by defualt) of the variable passed...in this case num3 address == 'X' address. Changes to num3 will in actuality be changes to 'X'.

- 4 5 6 // line 2 of output
- You are still in Display(3,2,1)
- You have already displayed the initial values passed
- The subprogram changes the local values* of num1, num2, and num3 to 4, 5, 6 respectively.
- * in this case, num3 is in actuality 'X', so 'X' is what is being changed, both the local scope of the subprogram and in the scope of main.
- You display the local num1, num2, num3 (see comment above) and exit

- 6 2 3 // final ouput after subprogram returns
- At this point, the variables used in the subprogram are now out of scope
- Main is using the variables X, Y, and Z
- Becuase X was passed by reference to the subprogram, where it was changed, the local (actually global in this case) value for X will have been changed.

--end email--