bmx-ng / bcc

A next-generation bcc parser for BlitzMax
zlib License
33 stars 13 forks source link

Again a wrong ByRef handling #583

Closed MidimasterSoft closed 2 years ago

MidimasterSoft commented 2 years ago

I can again observe a strange behavior related to "passed by ByRef" variables. This time it is a combination of a STRING variable send to a function "passed ByRef". Inside the function a SELECT/CASE branch does not compare correct. I observed the bug in DEBUG mode and I can reproduce it always with this example:

Global word:String = "[/size]"

Replacement word

Function Replacement(Tag:String Var)
    Select Tag
        Case "[/size]"
            Print "TRUE"
        Default
            Print "FALSE"
    End Select 
End Function 

without the VAR the SELECT/CASE reacts correct:

Global word:String = "[/size]"

Replacement word

Function Replacement(Tag:String)
    Select Tag
        Case "[/size]"
            Print "TRUE"
        Default
            Print "FALSE"
    End Select 
End Function 

Also this works perfect:

Global word:String = "[/size]"

Replacement word

Function Replacement(Tag:String)
    local t:String = Tag
    Select t
        Case "[/size]"
            Print "TRUE"
        Default
            Print "FALSE"
    End Select 
End Function 

Is this related to issue 577? You closed it three days ago...

Kerntrick commented 2 years ago

Strings are objects and so are passed by reference by default. There is no need for the 'var' keyword.

HurryStarfish commented 2 years ago

@Kerntrick There are two subtly different meanings of the word here. Being a reference is not the same thing as being passed by reference. String is a reference type, which means that variables to them only contain references instead of the objects themselves. But when passed to a function without Var, these references will still be passed by value. With Var, the reference is passed by reference, which means that assignments to the parameter variable will be visible outside the function.

SuperStrict
Framework BRL.StandardIO

Local x:String = "hello"
Print x ' hello
A x
Print x ' hello
B x
Print x ' b

Function A(s:String) ' passed by value
    s = "a" ' s works like a regular local variable, does not affect x
End Function
Function B(s:String Var) ' passed by reference
    s = "b" ' s refers to x; assigning to s is the same as assigning to x
End Function