Pop quiz time. What does the following VB6 code output to the immediate window?

Private Sub Form_Load()
    Dim strSmack As String
    
    strSmack = "unchanged"
    Me.changeString (strSmack)
    Debug.Print strSmack
    
    strSmack = "unchanged"
    Me.changeString strSmack
    Debug.Print strSmack
    
    strSmack = "unchanged"
    Call Me.changeString(strSmack)
    Debug.Print strSmack
End Sub

Public Sub changeString(ByRef strToChange As String)
    strToChange = "Changed"
End Sub


If you said...

unchanged
Changed
Changed


... you'd be right. Why?

Well, notice the space that's between changeString and (strSmack) in the first call. That's because we aren't "Call"-ing it explicitly, so the sub doesn't expect parameters between parenthesis. We "should" have called the sub like we do in the second call with no parens at all.

But since we do use parens, VB is evaluating the strSmack variable and passing in that value, not the string itself. It's sending in a clone of the strSmack object so there's no handle to strSmack at all. Crazy. It essentially evaluates to what we'd've gotten had we called this code:

Call Me.changeString((strSmack))

See what I mean? Instead of strSmack going in ByRef (which is, you should recall, the default; we coulda left that out of changeString's param list), a clone of strSmack is passed in instead, to which we have no handle at all.

*sigh* Love me some VB6. It has helped me buy my iMac at home, however and keep a roof over my head, so I won't complain too much just yet.