User Tools

Site Tools


mmbasic:byref_byval_vb_work_a_like

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

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)

…and…

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 passed to Subs use, effectively, the ByRef method - it is implicit and you can't change it. Changes to these variables by the Sub will be seen on the outside. If the original value is something you are going to need later, you have to take precautions against that destruction. Without too much thought, this could be simply making a copy that can be restored after the Sub has done its work, but there is a better, simpler, way…

Enclosing any value in parenthesis () causes an evaluation to be performed (the interpreter thinks you need it to do some maths or similar). The result (no matter how trivial the action) is stored on the heap in memory and the pointer to that (not the variable) is passed - a new, temporary pointer thus keeping the variable safe.

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 no difference 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.

mmbasic/byref_byval_vb_work_a_like.txt · Last modified: 2024/01/19 09:30 by 127.0.0.1