Page excerpted from Pass by Reference topic of a first year course in Structured Programming

A Swap Function

Consider the following highly desirable swap function:


Code Notes

1. Since variables are basically data containers that can only hold one piece of data at a time arg1 and arg2 can't just be swapped directly.

2. Instead, a 3rd container hold is created, then the piece of data from one of the two variables is copied to it(in this case arg1 but it wouldn't matter which one was started with).

3. Then the data from arg2 is copied to arg1, over-writing arg1's original data!

4. Fortunately, arg1's data has been preserved in in hold so now that data is copied back into arg2, completing the exchange.


The idea behind this swap routine is that it swaps the values of a pair of variables around. Swap routines are widely used. As we will find out, all routines to sort data into some sort of order work by comparing two pieces of data and, if they are out of order, swapping them.

If you were to run the routine in the TM you will find the swapping works just fine.

The only problem is, nothing happens from the calling routine's perspective. Here it is. Let's run it.


Code Notes

1. Step into main to the call to intSwap(a,b). The call should be loaded in the Expression Engine

2. Step through the call in the Expression Engine. Notice how a and b are replaced by their values.

3. Once the intSwap routine itself is reached, switch back to the source window and step through the parameter initialization. The parameters arg1 and arg2 are effectively both local variables belonging to the intSwap routine. They are initialized to the values passed in by the call. arg1 gets the first value, 5, and arg2 the second value, 3.

4. Step through the swap and observe the values in arg1 and arg2 swap perfectly.

5. Returning from intSwap, arg1 and arg2 go out of scope. a and b are untouched. The function hasn't affected them.


C passes by value so arg1 and arg2 are a copy of the original variables. As soon as we leave the intSwap routine arg1 and arg2 disappear and the original x1 and x2 are unchanged.As we saw, the intSwap function merrily swaps arg1 and arg2, but x1 and x2 are untouched because arg1 is a copy of x1 and arg2 is a copy of x2!

In the case of the factorial function, this behaviour was a desirable security feature.

Now suddenly it's a bug. How can we get around it?

Pass-by-Reference

C++ inherited C's pass-by-value design. But C++ added a new feature known as pass-by-reference to allow a function to access calling variables.

Here's a new version of the intSwap function that uses this pass-by-reference technique. The type of each parameter has been modified by adding an ampersand (&), technically known as a reference modifier.


Code Notes

1. Step into main to the call to intSwap(a,b). The call should be loaded in the Expression Engine

2. Step through the call in the Expression Engine. Now a and b turn blue to indicate a refernce to them is about to be passed.

3. Once the intSwap routine itself is reached, switch back to the source window and step through the parameter initialization. The parameters arg1 and arg2 are effectively both local variables belonging to the intSwap routine. They are initialized to the values passed in by the call. arg1 gets the first value, 5, and arg2 the second value, 3.

4. Step through the swap and observe the values in arg1 and arg2 swap perfectly.

5. Returning from intSwap, arg1 and arg2 go out of scope. a and b are untouched. The function hasn't affected them.


The only thing that has changed is the declaration of the two function parameters .

Now, instead of arg1 and arg2 being ints, they are formally called references to ints. In the syntax of C++ a reference to int (or reference to double or reference to char ) is a distinctly different type from an int (or double or char).

The variables are the function parameters and they are references to the original variables.

Note that the call to the pass-by-reference (useful) version of the intSwap function is identical to the (useless) pass-by-value version.

Notice, there is no way you can tell by looking at a call whether the arguments are being passed by value or by reference. You have to look at the function declaration to know.

void intSwap(int& x1, int& x2);

is the declaration for a function that passes its arguments by reference while

int factorial(int n);

is the declaration for a function that passes its arguments by value.

It should be noted that although the Teaching Machine supports windows into different types of memory (e.g. the heap) the instructor of this beginning course has configured the TM only to show the stack and has relabelled it as simply "memory". See shallow vs deep copy and linked lists for other instructor generated configurations.

Examples Shown in Full