In this example, I am going to demonstrate the difference of passing a variable into a subsequence by value versus passing by reference.
Pass By Reference
For those of you used to TestStand, you know that TestStand defaults to passing all variables into a subsequence by reference. This is useful considering some procedural languages actually require you to use pointers in order to pull this off. Passing by reference is also a more efficient use of memory as temporary copies of variables aren’t being created, taking up space. However, users of TestStand need to be aware of this default setting because variables you are passing into the subsequence may be getting manipulated unintentionally. This might leave you debugging a test script for hours; not understanding why it keeps failing on you. Allow me to demonstrate…
Starting out with a new sequence, I am going to create two (2) local variables. The first variable I am going to make is a number and I will call it ‘Year’ and the second variable will be a string called ‘Month’. Next I will add a sequence in my sequence file and call it ‘PassByRefandValueSequenceCall’. Under the MainSequence I will now insert a Sequence Call step and have it call the ‘PassByRefandValueSequenceCall’ sequence. Finally, I will insert a Statement step into the MainSequence and initialize my two newly created variables. I am going to initialize ‘Year’ to 2011 and ‘Month’ to “September”. Figure 1 below shows what this sequence currently looks like.
The next thing I need to do in order to set up my example is I need to configure the ‘PassByRefandValueSequenceCall’ sequence to accept my two new variables ‘Year’ and ‘Month’. Therefore, within the ‘PassByRefandValueSequenceCall’ sequence, I am going to add two parameters; one number and one string. The first parameter I will call ‘IntegerPassedfromMainSequence’ and the second will be ‘StringPassedfromMainSequence’. Now I am going to add two Statement steps changing the values of the two parameters. As you can see in Figure 2 below, when this sequence call is made, ‘Year’ will be changed to 2012 and ‘Month’ will be changed to “October”.
Now that I have created my two parameters, I need to go back to the MainSequence and pass in my two local variables into ‘PassByRefandValueSequenceCall’. Figure 3 below shows how the Sequence Call was configured. Notice how both variables are being Passed by Reference.
So now what I want to do is show you what passing by reference means in TestStand. Remember, my sequence creates two variables ‘Year’ and ‘Month’, sets them to 2011 and “September”, then passes them by reference to ‘PassByRefandValueSequenceCall’. Within this sequence, my script then changes ‘Year’ to 2012 and ‘Month’ to “October” before exiting. So what value are my variables once ‘PassByRefandValueSequenceCall’ is done executing and it returns back to the MainSequence? In order to demonstrate the answer I am going to insert some Message Boxes. I will add two message boxes inside ‘PassByRefandValueSequenceCall’ and two message boxes in the MainSequence after the sequence call is done executing. Figure 4 and 5 below show what my sequence now looks like.
Now I am ready to execute my sequence and show what it means to pass a variable by reference. Figure 6 below shows the results.
Are you amazed? Didn’t think so. Look how after the two variables are manipulated inside the ‘PassByRefandValueSequenceCall’ the local variables in the MainSequence now show the same value. This makes sense since we are passing in a reference to the variables in memory and not some temporary copy. But what if you didn’t want the sequence call to alter the values of the passed in variables? What if you intended the variables to be constants and didn’t expect them to change? You could just insert a couple of Statement steps and save off copies of the variables into other temporary variables or you could just change the sequence call to accept the passed in variables by VALUE.
Pass By Value
Taking the existing script we created above, I am now going to change the parameters to be passed by value rather than reference. To do this in TestStand, you simply need to click on the parameter and uncheck ‘Pass By Reference’. Figure 7 below shows an example.
Now that both parameters have been configured to be passed by value, we are ready to execute our script again. But first, I want to go back to the MainSequence and show how the sequence call looks now. Figure 8 below now confirms that both parameters are indeed passed by value.
So now what happens whenever we execute the sequence?
Figure 9 shows us how the original values of the local variables inside the MainSequence remain untouched. This is because the ‘PassByRefandValueSequenceCall’ did not alter the memory locations of the original variables but rather copies of them. One can see how this could be useful whenever variables being passed in are being treated as constants. Remember though that passing by reference is the preferred and more efficient method. Hence, NI defaults to it!