ByVal

Declaration specifier to explicitly pass a parameter by value

Syntax
	ByVal param KeyPgAsAs DataTypedatatype

Usage
	[ KeyPgDeclareDeclare ] { KeyPgSubSub | KeyPgFunctionFunction } proc_name ( ByVal param KeyPgAsAs DataTypedatatype  )

Description
	ByVal in a parameter list of a declare statement causes a copy of the 
	variable to be passed to the procedure (for example, a sub or function) 
	by its value.

	This means that if the value of the variable x is passed, then the 
	original variable x will not be modified in any way; however, if the 
	variable were passed KeyPgByrefByRef, the value of the original variable x could 
	be modified by the called function.

	Opposite of KeyPgByrefByRef.

	The ByVal keyword is also used in the context of Byref KeyPgByrefParameters and 
	KeyPgByrefFunctionFunction Results, where it can be used to explicitly override the 
	by-reference semantics in order to pass or assign a pointer as-is to a 
	Byref parameter or function result. For reference:
		* ProPgPassingArgumentsManually passing pointers to by-reference parameters
		* ProPgReturnValueManually returning pointers as-is from Byref functions

	Note: ByVal (passing by copy) is good for small objects (4 or 8 bytes, a 
	bit more will still be ok) that are easy to copy, like numeric types. 
	Passing ByVal avoids the overhead of the pointer used by KeyPgByrefByRef.
	KeyPgByrefByRef is better for passing huge objects like strings or big UDTs that 
	should not be copied. Even though KeyPgByrefByRef has some overhead because it has 
	to pass a pointer (and dereference at each access to the object), this 
	is still better than copying a multitude of bytes on to the stack 
	every-time the procedure is called.

Example
	Sub MySub(ByVal value As Integer)
	   value += 1
	End Sub

	Dim MyVar As Integer

	MyVar = 1
	Print "MyVar: "; MyVar 'output = 1
	MySub MyVar
	Print "MyVar: "; MyVar 'output = 1, because byval won't change the values passed into it globally.
	Sleep
	End

Dialect Differences
	* In the CompilerOptlang-lang fb dialect, ByVal is the default parameter passing 
	  convention for all built-in types except KeyPgStringString and user-defined KeyPgTypeType 
	  which are passed KeyPgByrefByRef by default. The KeyPgZstringZString and KeyPgWstringWString built-in 
	  types are also passed KeyPgByrefByRef by default, but passing ByVal is 
	  forbidden. Arrays are always passed KeyPgByrefByRef and the use of the specifier 
	  KeyPgByrefByRef or ByVal is forbidden.
	* In CompilerOptlang-lang qb and CompilerOptlang-lang fblite dialects, KeyPgByrefByRef is the default parameter 
	  passing convention.

Differences from QB
	* QB only used ByVal in declarations to non-Basic subroutines

See also
	* ProPgPassingArgumentsPassing Arguments to Procedures
	* KeyPgDeclareDeclare
	* KeyPgByrefByRef

