Android Question Odd Behavior of Return

scGuy

Member
Licensed User
I understand that code execution in a sub ends at the return statement. In a class module (b4a 8.80), I was creating a trivial public sub that returns the value of the private variable sErrorMessage, but I also wanted to clear the sErrorMessage value, so that if LastError is called twice in a row, it will only return a value one time. Ok that's easy. Except of course I cannot set sErrorMessage="" after the Return statement, because it will never execute. So I did this:


B4X:
Public Sub LastError As String
 Dim sTemp As String
 
 sTemp=sErrorMessage
 sErrorMessage=""
 Return sTemp
End Sub
However the above, in all cases, returns empty string, even if sErrorMessage had a value. I'm guessing the value is getting assigned to sTemp, how could it not, but then the Return of sTemp doesn't work as expected -- maybe because the variable is local and getting deallocated when the sub folds up? Still the very simple example above makes me think something odd is going on with Return. How should I have done this? One workaround I've found that works is removing the Dim statement and declaring sTemp in Class_Globals. I've stared at this for about 20 minutes wondering if I'm losing my mind. Is there some other obvious reason I can't return the value as shown above? Just curious at this point. Thanks!
 

Pendrush

Well-Known Member
Licensed User
You can try this:
B4X:
Public Sub LastError As String
   Dim sTemp As String 
   sTemp = CopyObject(sErrorMessage)
   sErrorMessage = ""
   Return sTemp
End Sub

Sub CopyObject(o As Object) As Object
   Dim s As B4XSerializator
   Return s.ConvertBytesToObject(s.ConvertObjectToBytes(o))
End Sub
 

afields

Member
Licensed User
Helo!
What's beyond strings, numbers in generaly what relate to variables is the memory. each time you declare a variavle with "private ss as string" you are creating memory space for that variable and having in return the frist place in memory where you ( via program and via os) are going to put your data.
When you say that a=b ( just that) you are saying that the frist place of a is going to be the same as the first place of b.
But if you say in Sub LastError for exemple:
B4X:
Public Sub LastError As String
    Dim sTemp As String

    sTemp=sErrorMessage.SubString(0)
    sErrorMessage=""
    Return sTemp
End Sub
then you are creating a new place where to put your data and adicionaly with that sTemp=sErrorMessage.SubString(0) you are in fact copying your data to that new place.
From now on, you will have two places in memory in which you have the same data.
it's more or less what the pendrsuh answer is also...
 

agraham

Expert
Licensed User
The code should (does!) work assuming that sErrorMessage actually holds a value. Are you sure that LastError is not being called twice and so losing the original value in the first call to LastError.

Strings in Java (and C# and other languages) have "value semantics" even though they are implemented as reference types. This means they are always passed by copying them and not by passing a reference to them. In actuality strings are passed by reference but any attempt to change them results in a new string and a new reference being generated so they behave like other true value types such as Ints and Doubles.

What @afields is trying to describe above (I think) are reference semantics, which do apply to "proper" objects. Objects are passed by reference and their properties and fields can be changed using the reference. Arrays for example are passed by reference so you can change the value of an array element and the caller sees the change.
 
Top