I am struggling to understand pass by value and pass by reference in VB6. I understand these concepts fully in Object Oriented programming languages like .NET and Java (I realise that Java doesn't have pass by reference). Have a look at the code below:
Private Sub Form_Load()
Dim Test As Integer
Test = 1
TestFunction Test 'line 5
MsgBox (Test)
End Sub
Private Sub TestFunction(ByVal i As Integer)
i = i + 1
End Sub
When I put brackets around Test on line 5, then the message box prints 1 as I would expect. Now have a look at the code below:
Private Sub Form_Load()
Dim Test As Integer
Test = 1
TestFunction Test 'line 5
MsgBox Test
End Sub
Private Sub TestFunction(ByRef i As Integer)
i = i + 1
End Sub
The message box prints 2 as I would expect. However, if you add brackets to line 5 then the message box prints 1 as I would not expect. It appears that the calling function can pass by value even if the variable defined in the called function is ByRef. It appears not to be the case vice versa, i.e. if the called function has a signature with a variable defined as ByVal then it will always be ByVal (even if there are no brackets around the variable in the calling function). What is the thinking behind this in VB6? I realize that this is a basic question in VB6 but it has confused me. I have read the MSDN documentation and I realize that this is all true, however it does not explain the reasoning behind it.
The main difference between pass by value and pass by reference is that, in a pass by value, the parameter value copies to another variable while, in a pass by reference, the actual parameter passes to the function. A computer program is a set of instructions that directs the CPU to perform a certain task.
Pass by Value: The method parameter values are copied to another variable and then the copied object is passed, that's why it's called pass by value. Pass by Reference: An alias or reference to the actual parameter is passed to the method, that's why it's called pass by reference.
"Passing by value" means that you pass the actual value of the variable into the function. So, in your example, it would pass the value 9. "Passing by reference" means that you pass the variable itself into the function (not just the value). So, in your example, it would pass an integer object with the value of 9.
ByVal stands for “By Value,” i.e., when the subprocedure calls in from the procedure, the value of the variables is reset to the new value from the new procedure called in.
This is a classic gotcha in VB6. It is explained in the VB6 manual. In this code below, VB6 treats the argument as an expression (Test) rather than a variable reference
TestFunction (Test)
In order to pass a reference to the variable either omit the brackets or use the legacy Call
statement (which requires brackets)
TestFunction Test
Call TestFunction(Test)
VB6 allows you to pass expressions to ByRef
arguments even if the method changes them. Eg you can write
TestFunction (Test + 2)
The compiler creates a temporary copy and passes that by reference. VB.Net uses brackets in a similar way.
You can also get the compiler to create temporary copies if TestFunction takes two arguments like this:
TestFunction (one), (two)
And you can get temporary copies even with Call
if you double your brackets, adding an extra unecessary pair:
Call TestFunction((Test))
Enclosing any expression within parentheses causes that expression to be evaluated first before doing anything else, even when that expression is only a single variable. In your case, the result of that expression is then passed as an argument.
So, you are in fact passing the argument by reference. But the argument you are passing is the result of the expression and not the original variable. This is why the original variable does not get updated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With