dcsimg
Results 1 to 10 of 10

Thread: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

  1. #1

    Thread Starter
    Member
    Join Date
    Aug 2013
    Posts
    40

    Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    Can someone please explain this to me?
    Why do the parentheses in the sub call have this effect?
    Thanks

    'Form with one command button
    Code:
    Option Explicit
    
    Private Sub proc(ByRef s As String) 'string parameter passed by reference
        s = "altered"
        MsgBox (s) 'displays : altered   as expected
    End Sub
    
        
    Private Sub Command1_Click()
    Dim s As String
        s = "original"
        proc (s)  ' sub procedure call with parentheses acts as though ByVal
        MsgBox (s) 'displays : "original"              should display "altered" ???
        
        proc s  ' sub procedure call without parentheses acts as expected, ie ByRef
        MsgBox (s) 'displays : "altered"      as expected
    End Sub

  2. #2
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,537

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    vbrad,

    It's not exactly changing it from ByRef to ByVal. Rather, when you put parentheses around anything, VB6 is going to create a temporary variable to hold the results of the "expression evaluation". For instance, (iSomeVar) really isn't much different from (iSomeVar + 1 - 1). They're both seen as expressions, and a temporary variable is going to be created in both cases.

    Now, even though you really don't have access to it, this temporary variable is still being passed ByRef. But, since you don't have access to it, you're not going to see any changes to it by the called procedure, and they're certainly not going to be put back into the original iSomeVar (my example).

    Maybe That'll Help,
    Elroy
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  3. #3
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    When you use a pair of parentheses in an expression you are commanding the compiler to "evaluate this expression as a temporary value." Passing a temporary as a ByRef argument works, but of course it doesn't get "de-evaluated" to update any particular variable that was used in the expression even if the expression has just one simple term.

    Just don't do it. And no, don't use the crutch of the obsolete Call verb to pave over it.

  4. #4

    Thread Starter
    Member
    Join Date
    Aug 2013
    Posts
    40

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    Thanks Elroy and Dilettante, I get it now.
    The only thing that still bothers me is that if I alter the procedure to a function it doesn't do the evaluation?
    As in

    Code:
    dim dummy as string
    dummy = proc(s) 's is not evaluated and variable in the calling code is altered.

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,537

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    Hmmm, that's not my experience. ByRef is the default for both Sub and Function procedures. It's not often done, but you can certainly alter (and return) arguments that are passed into a function:

    Code:
    
    Option Explicit
    
    Private Sub Form_Load()
        Dim a As Long
        a = 55
        Debug.Print TestFn(a)   ' <--- reports 77
        Debug.Print a           ' <--- reports 88, as changed by our call into TestFn.
    End Sub
    
    
    Private Function TestFn(a As Long) As Long
        TestFn = 77
        a = 88
    End Function
    
    

    EDIT1: Now, if we put parentheses around a when calling TestFn, we'll create an expression with the associated temporary variable. For instance:

    Code:
    
    Option Explicit
    
    Private Sub Form_Load()
        Dim a As Long
        a = 55
        Debug.Print TestFn((a)) ' <--- reports 77, NOTICE EXTRA PARENTHESES!!!
        Debug.Print a           ' <--- reports 55, "a" wasn't actually passed, but rather a temporary variable.
    End Sub
    
    
    Private Function TestFn(a As Long) As Long
        TestFn = 77
        a = 88
    End Function
    
    
    Last edited by Elroy; May 9th, 2019 at 10:36 AM.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    For a function call the outer parentheses are part of the call syntax, not a request to evaluate and create a temporary.

  7. #7

    Thread Starter
    Member
    Join Date
    Aug 2013
    Posts
    40

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    Sorry I know I am possibly coming across as a bit thick here, but you had to introduce double parentheses to cause evaluation of the contents for a function call.
    So the outer set of parentheses in a function call do not cause evaluation whereas they do for a sub call.

    Edit Thanks Dilettante and Elroy, I get it now.

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,206

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    It is probably clearer when you have 2 or more arguments.

  9. #9
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,537

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    Yes, I think I'm being a bit pedantic here. But yes, you've got to differentiate parentheses that encapsulate a list of arguments versus parentheses that create expressions. As Dil says, maybe it's more clear which is which when you've got 2 or more arguments.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  10. #10

    Thread Starter
    Member
    Join Date
    Aug 2013
    Posts
    40

    Re: Parentheses around argument of Sub changes behaviour from ByRef to ByVal

    Thanks again guys, it's amazing how long I managed to breeze along not knowing something so fundamental.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width