Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ByRef and ByVal

Status
Not open for further replies.

BigCatMCS

Programmer
Apr 29, 2004
57
US
in VB 6, when your passing an argument on to a called procedure, if you use ByVal, does the variable (that you will be using as an argument) from the calling procedure stay the same? But if you use ByRef, will it change?
 
ByVal means that the procedure is not allowed to change the value. ByRef (the VB6 default) means that the procedure is allowed to change it.

Things get tricky when you're talking about simple objects vs. complex objects. The above rules apply for variables of type int, string, bool, etc. But when the variable is an object variable, what ByRef/ByVal mean is that the object variable itself won't change -- but the contents of the object might.

A good example is if you pass a Xml DomDocument to a procedure ByVal.

The "ByVal" says that the DomDocument after the procedure is called will be the same one that was passed in. However, inside the procedure, the contents of the Xml document could be changed, and those changes would be visible outside the procedure.

This pseudo-code illustrates this. The DomDocument doesn't change, but it's contents does.
Code:
' Not real code
Dim MyDoc As New DomDocument40

MyDoc.Load("c:\somefile.xml")

debug.print MyDoc.xml

Call SomeProc(MyDoc)

debug.print MyDoc.xml

'---------
Public Sub SomeProc(ByVal MyDoc as DomDocument40)

  ' this is really bad practice
  MyDoc.SelectSingleNode("//Somenode").Text = "New Value"

End Sub
Chip H.


____________________________________________________________________
Click here to learn Ways to help with Tsunami Relief
If you want to get the best response to a question, please read FAQ222-2244 first
 
Another question...is ByRef by default? What I mean is, that if you leave the arguments on the called procedure w/out ByRef and ByVal - will it default to ByRef?

Also, the arguments in the calling procedure will not be changed - am I correct? No matter if you do ByRef or ByVal?

For some reason, I'm getting confused on this.
 
If you don't specify byref or byval, the default is byref. If the data type is a "simple" data type like integer or string.... changing the value of the parameter inside the subroutine will change the value outside the subrouting.

I had a lengthy discussion (a couple months ago) with one of my programmers. He wanted to use byref for EVERY parameter, everywhere. His argument was that byref ONLY passes the address where the data is stored, not the actual value, so byref is faster than byval.

Technically he was right about byref being faster, however. My point was... in VB you get intellisense when you call a function. if the parameter is a byval parameter, the intellisense will tell you that. I think that is VERY valuable information to know. I also ran a test to determine the speed difference, and it was negligible.

If you want to remember just one thing about this lengthy reply.....

Use byval when the parameter will NOT be changed inside the subroutine.

Use byref when the parameter will be changed inside the subroutine.
 
ByVal/ByRef is part of the "contract" between the author of a function/sub/method and the programmer calling it. If you call a procedure where one or more parameters are ByVal, you know that the procedure will not alter your variable.
ByVal means that the procedure is not allowed to change the value. ByRef (the VB6 default) means that the procedure is allowed to change it.
While this is true, it is also false. It depends on how you interpret it.

A ByVal parameter is a local copy of the passed parameter expression's value. As such, the copy can indeed be modified within the called routine. The point is that the altered value does not have any affect on the calling routine's variable or expression passed.

So you could say: "ByVal means you are free to modify the variable without causing side-effects in the calling code. ByRef means you cannot change it or else you do risk side-effects."

It's also true of course that people can get wrapped around the axle when they consider object references. The trick is to realize that you do indeed pass object references and not objects to a called procedure.

Thinking of the reference being passed ByVal/ByRef makes it all clearer: a ByVal reference doesn't keep the procedure from modifying the referenced object, you merely can't change the value of the reference in the calling program's variable. With a ByRef object reference parameter however, the called routine can indeed "point" the caller's reference to some other object.

In most cases then, object references should be passed ByVal, just as with most data. In general you should use ByRef when the developer of the function/sub intended that the routine modify one or more passed parameters. The "efficiency" issue only arises when passing long strings or arrays.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top