ByREF & ByVAL - (VB work-a-like)

Modified on 2021/11/25 17:48 by CaptainBoing — Categorized as: Maths, Memory, Program Flow, Programming Method, Strings

Not a direct work-a-like but a work-around...

MMBasic, good as it is has some omissions forced on it by the target environment - there is only so much you can do in the small memories of micro-controllers.

When passing arguments into Subs and Functions, programmers of more heavy-weight languages are used to being able to specify the method with which a variable is passed.

VB, for instance, supports the following:

Sub MySub (ByVal x As Integer)

Or

Sub MySub (ByRef x As Integer)

The first passes the actual VALue of the variable. Any actions performed on that variable inside the Sub or Function are not reflected back into the passed argument. The second passes the pointer (REFerence) of the variable. This means that any actions performed on the variable by the Sub, will alter it - the variable will change value, so when you come back from the Sub, the calling program can expect a different value in that variable. This can be exploited as a way to get more than one result from Functions but can also lead to tricky bugs.

With MMBasic, all variables are passed using, effectively, the ByRef method - it is implicit and you can't change it. Functions and Subs that perform actions on these arguments will alter the value of the variable in the calling code. If this is something you are going to need later, you have to take precautions against that destruction. Often this involves making a copy that can be restored after the Sub has done its work, but there is another, simpler, way...

Enclosing the passed variable in parenthesis () causes an evaluation to be performed. The result is stored on the heap in memory and the pointer to that (not the variable) is passed.

Consider the following demonstration:

	Dim Integer x,z
	x=10
	z=MyFunc(x)	
	Print x
	
	
	x=10
	z=MyFunc((x))	
	Print x
	
	
	Function MyFunc (a As Integer)
		a=a/2
	End Function

MyFunc trashes the passed-in variable by acting directly on it (as its alias 'a') and this can be seen in the first example with x changing value from 10 to 5. The second wraps X in an additional set of parenthesis. This calls the evaluator to work out the result of the expression (there is none really) but the evaluation is done nonetheless with the result being stored temporarily on the heap in RAM. The "ByRef" pointer passed to MyFunc is that of the temporary area and not of the original variable leaving it intact and thus emulating ByVAL.

This trick works for all variable types, e.g. (a$), (b%) and (c!) will all remain intact and safe from the vandalism of the Sub.