VB6 pasar por valor y pasar por referencia

Estoy luchando por comprender el valor de paso por paso y paso por referencia en VB6. Entiendo estos conceptos completamente en lenguajes de progtwigción orientados a objetos como .NET y Java (me doy cuenta de que Java no tiene acceso por referencia). Echa un vistazo al código a continuación:

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 

Cuando coloco corchetes alrededor de Prueba en la línea 5, el cuadro de mensaje imprime 1 como era de esperar. Ahora eche un vistazo al código a continuación:

 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 

El cuadro de mensaje imprime 2 como era de esperar. Sin embargo, si agrega corchetes a la línea 5, el cuadro de mensaje imprime 1 como no esperaba. Parece que la función de llamada puede pasar por valor incluso si la variable definida en la función llamada es ByRef. Parece que no es el caso al revés, es decir, si la función llamada tiene una firma con una variable definida como ByVal, entonces siempre será ByVal (incluso si no hay corchetes alrededor de la variable en la función de llamada). ¿Cuál es el pensamiento detrás de esto en VB6? Me doy cuenta de que esta es una pregunta básica en VB6 pero me ha confundido. He leído la documentación de MSDN y me doy cuenta de que todo esto es cierto, sin embargo, no explica el razonamiento detrás de esto.

Este es un gotcha clásico en VB6. Se explica en el manual de VB6 . En este código a continuación, VB6 trata el argumento como una expresión (Prueba) en lugar de una referencia de variable

 TestFunction (Test) 

Para pasar una referencia a la variable, omita los corchetes o use la statement de Call heredada (que requiere corchetes)

 TestFunction Test Call TestFunction(Test) 

VB6 le permite pasar expresiones a argumentos ByRef incluso si el método los cambia. Ej. Usted puede escribir

 TestFunction (Test + 2) 

El comstackdor crea una copia temporal y la pasa por referencia. VB.Net utiliza corchetes de manera similar .

También puede obtener el comstackdor para crear copias temporales si TestFunction toma dos argumentos como este:

 TestFunction (one), (two) 

Y puede obtener copias temporales incluso con Call si duplica sus corchetes, agregando un par extra innecesario:

 Call TestFunction((Test)) 

Encerrar cualquier expresión entre paréntesis hace que esa expresión se evalúe primero antes de hacer cualquier otra cosa, incluso cuando esa expresión sea solo una variable única . En su caso, el resultado de esa expresión se pasa como un argumento.

Entonces, de hecho está pasando el argumento por referencia. Pero el argumento que está pasando es el resultado de la expresión y no de la variable original. Esta es la razón por la cual la variable original no se actualiza.