Passing and returning arrays

BlitzMax Forums/BlitzMax Programming/Passing and returning arrays

Grey Alien(Posted 2006) [#1]
Hi, so far in BMax I haven't used arrays much (I have plenty in other languages) but now I'm wondering what the various syntaxs are for the following:

1) passing an array into a function. i.e. how to call the function and how to declare the function. I assume an array will be passed as a variable automatically without me having to put "var" after it?
2) returning a new array from a function. i.e. is this even possible, like say I declare an array of a certain size (or no size?) and I call a function and assign the return value, which is an array, to the array that I declared.

Maybe I should just stick to TLists ;-)

Thanks for any help.


AlexO(Posted 2006) [#2]
To pass an array:
function passAnArray(myArray:float[])
   local theSizeIWant:int = 3
   if myArray.length <> theSizeIWant then
        return 
   end if
end function


To return an array:
function returnArray:float[]()
   local retArray:float[3]
   return retArray
end function


of course float is just the datatype, can be whatever.


Grey Alien(Posted 2006) [#3]
Thanks Alex. seem to have figured it out:

Function ArrayFiddler:String[](In$[])
   Local out$[]
   return out
End Function

Local myarray$[]
myarray = ArrayFiddler(myarray)


Now I know I could just modify the In array in the function and because it's passed as a var (isn't it?) it would remain modified after the function, but my function is pretty complex and it's easier to make a new array and pass that out.

Anyway another question arise. Will BMax garbage collection handle this line:

myarray = ArrayFiddler(myarray)

properly because the original myarray is now being overwritten, all the strings in the original one need to be freed and so does the original array. Will that be done? I hope so...


Grey Alien(Posted 2006) [#4]
some test code that shows arrays ARE passed as var (of course). Interestingly the compiler lets you redundantly write var after the array in the function parameters...

Strict
Local test$[2]

test[0] = "hello"

fiddle(test)

Print test[0]

Function fiddle(in$[])
	in[0] = "goodbye"
End Function



AlexO(Posted 2006) [#5]

...because the original myarray is now being overwritten


Blitzmax handles arrays as special objects from what I understand. You aren't really 'overwriting' it technically. You're just changing what myarray points to. So the original array no longer has a reference to it...and therefore gets garbage collected.


Grey Alien(Posted 2006) [#6]
Thanks.

yep thought so. It handles them as objects but we can't as developers (i.e. no Extending allow, shame).

I just bunged this round the function call:

		GCCollect
		Local old = GCMemAlloced()
                myarray = ArrayFiddler(myarray)
		GCCollect
		Notify old + "  " + GCMemAlloced()



And it's the same, which confirms it.


Steve Elliott(Posted 2006) [#7]

Maybe I should just stick to TLists



Well yes TLists are designed for games in mind really aren't they? But if you have data that doesn't change arrays are certainly faster.


Grey Alien(Posted 2006) [#8]
TLists are just more OOP I feel and less techie and better for changing data for sure you are right.


Yan(Posted 2006) [#9]
Interestingly the compiler lets you redundantly write var after the array in the function parameters...
Not quite redundant...
Local test[10]

Print test.length

ResizeMe1(test, 20)

Print test.length

ResizeMe2(test, 30)

Print test.length

End

Function ResizeMe1(array[], size)
	array = array[..size]
End Function
	  
Function ResizeMe2(array[] Var, size)
	array = array[..size]
End Function



Grey Alien(Posted 2006) [#10]
Yan: What the hell! so you can change the contents of array slots without var but not the size, well that is worth knowing. Thanks.


Bobysait(Posted 2016) [#11]
Very old post, but yan's intervention is wrong and might lead to false statement :

Arrays are NOT passed by reference !
It looks like it because when we pass an array as argument to a function, the handle of the array in the argument also hold the pointer to the original data.
So the data can be modified, but not the variable itself.
It's Like using "const SomeType MyVariable" in C
-> the reference object can't be modified (whyle its content can be).

Which leads to the false statement seen above :

Function ResizeMe1(array[], size)
	array = array[..size]
End Function

This function does nothing but creating a "NEW" array of a new size.
Slicing an array ALWAYS create a NEW array, it doesn't affect the original.

And as long as it's not returned in any way, it will be garbage collected, and nothing more.
So it does not affect the variable "array[]" passed as argument as it's missing the "Var" keyword.
-> So, the only conclusion is :
The content of the array can be modified when passing an array (else it would make no sense to send an array ^^), but slicing an array will ALWAYS create a "New" array. It doesn't modify the original.


Function ResizeMe2(array[] Var, size)
	array = array[..size]
End Function

While, this works because the "Var" keywords specifies that the "array[]" variable is a reference.
So, whenever its allocation is modified, the original variable is affected to
And by the way, we HAVE TO pass a "variable" for this to work.

For example, passing an array returned by a function will just fail at compile time (because it's not a variable).

Function Gen:Object[](size:Int)
 Return New Object[size];
End Function

Function Slice(a:Object[] Var,newSize:Int)
 a = a[..newSize]
End Function

Slice(gen(10), 20);

This won't work because it's missing a valid "variable reference".


----------------------------------------------------------------

Just imagine you have a letter to send, but you're very bad in grammar
you send it to your friend to get it corrected.
He makes the correction and send it back to you.
You can send the letter (or copy it to get a clean sheet)

That's what happens when you use "Var" -> you really send the paper.


Now, imagine you've got a mail to send ...
You send a copy to your friend
he modifies it and send it back to you
So, there is actually 3 copies of the mail
- the original
- the copy you sent
- the copy he sent back.
If you want to send the mail, you'll have to send the last one, because the original is still full of errors.

And THAT's what happens when you don't use the "Var" keyword :)

----------------------------------------------------------------



I Hope I'm clear enough for thoose who got there for any reason.


LT(Posted 2016) [#12]
Ahem...Yan was not saying that arrays are passed by reference. He(she?) was making the same point you are; correcting Grey Alien's assumption.


Bobysait(Posted 2016) [#13]
That's true, but the fact the original post is ten years ago and nobody corrected the Grey Alien's assumption, makes me feel like he didn't noticed it either (and if he did, it should have been corrected).

But whatever, his point is useless without further explanation, and that's probably what led Grey alien to a bad conclusion.

As a map is nothing without its scale, an example is useless without comments.

That's maybe weird to come and suggest a modification to an old (and probably useless) topic, but what has been said is about the basis of the programmation. Anyone who would take it as is will come to great trouble and might even never understand why.
I think that's important enough to just let a small message to prevent (potential) future users.