Try the following code: ``` Sub Main() Dim x As String x = "foo" ' (1) Aux(x) ' (2a) MsgBox x ' ==> "bar", expected "foo" End Sub Sub Aux(y As String) ' (2b) y = "bar" ' (3) End Sub ``` What is expected: (1) `x` is a reference to a string "foo". (2a) and (2b) `y` is a **copy** of `x`, that means that both `x` and `y` are independent references to the string "foo". (3) `y`, by affectation, refers to a new string "bar". This is a weird behavior because `Aux` should only get a copy of `x` and the reference `x` should not be updated to have the new target value "bar". I have never seen this behavior in any other language. (The closest thing I can think of is the C preprocessor pitfalls.) ($ uname -a Linux jferard-Z170XP-SLI 5.15.0-46-generic #49-Ubuntu SMP Thu Aug 4 18:03:25 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux) Maybe related to: https://bugs.documentfoundation.org/show_bug.cgi?id=145279
Actually this is the intended behavior. It's by design in Basic (and in VBA as well). According to Pitonyak's book about LO Basic: "By default, arguments are passed by reference rather than by value. In other words, when the called subroutine modifies an argument, the caller sees the change. You can override this behavior by using the ByVal keyword." To avoid changing the value of x, you need to use the ByVal keyword: Sub Main() Dim x As String x = "foo" ' (1) Aux(x) ' (2a) MsgBox x ' ==> "bar", expected "foo" End Sub Sub Aux(ByVal y As String) ' (2b) y = "bar" ' (3) End Sub I'm closing this as NAB.
I disagree. Passing arguments by reference is usual in programming languages (Java, Python, ...), at least for non primitive types. But this behavior is very specific and in my opinion a bug. > when the called subroutine modifies an argument, the caller sees the change. This is not a modification, this is a *new assignment*. This is a modification : ``` Sub Main() Dim x() As Integer x = Array(1, 2, 3) Aux(x) MsgBox x(0) ' ==> 10 as expected, because the array is passed by reference End Sub Sub Aux(y As Variant) y(0) = 10 ' modification of the array referenced by both x and y. End Sub ``` > It's by design in Basic (and in VBA as well). Not in Visual Basic .NET (.NET Core): https://tio.run/##VY/NDoIwEITP9CkmXEoPmqhnTPy7yYlEzy2spgm2poApT49FguicZrOT2W9falFYR32f2bKtCJf9aBjLW4VMapMIFh31Ax67GnnjtLmzyCNFfLM2xiSOZBWSu9YnXuBHYbGWgk3jwZraVrS8Ot3QWRsa4hxpugUPhRyyBvknFQ2V7GRKBI4RZqjuZggx16twuBuIlHR/RBvxrQA@dvyu798 Please check in VBA (really), I can't but I'm pretty sure that the output will be "foo" and not "bar".
Indeed you're right. I tested again and in MS VBA the default is ByVal. I must have made some mistake in my previous testing. However, for some reason LibreOffice Basic chose to use ByRef as default. See [1] for more info. The strange bit is when you use "Option VBASupport 1" and the behavior does not change. If LO and MS Basic are different in this regard, then using this option should change the behavior in LibreOffice to make it behave as in VBA. Naturally, since LO chose to go with ByRef as default, we cannot change it now to avoid breaking backwards compatibility. But there seems to be something wrong with VBA support. @Mike do you have any opinion on this? Why is ByRef the default in LO? Should we change the default to ByVal in VBA support? [1] https://help.libreoffice.org/7.4/en-US/text/sbasic/shared/03090409.html
According with the LibreOffice BASIC Programming Guide (https://wiki.documentfoundation.org/Documentation/BASIC_Guide#Procedures_and_Functions), that behavior is the expected since "Parameters are normally passed by Reference in LibreOffice Basic. Changes made to the variables are retained when the procedure or function is exited"
I see, the example is very similar to the one I gave. The specific part is: "Changes made to the variables are retained when the procedure or function is exited:". But this is not an automatic consequence of passing parameters by reference. In most programming languages I know, even if you pass a parameter by reference, the parameter is a copy of the reference (not of the target of the reference itself) and a new assignment of the parameter has no effect outside of the function. (A modification of the target value of the reference is of course quite a different thing.) I still believe that's a misleading behavior (not to say a bug), maybe a legacy of GoSub/Return, but I concede. Regarding the VBA support issue, I can confirm that `Option VBASupport 1` does not change the behavior (same config as in the first post).
(In reply to Rafael Lima from comment #3) > Why is ByRef the default in LO? Because that is how this language was implemented (and maybe specified, when StarDivision developed it). Nothing can be done here. > Should we change the default to ByVal in VBA support? Anything that works in VBASupport mode differently compared to VBA is a bug.
The original issue is indeed not a bug. Please close this ticket (I can't). Feel free to open a new ticket about the VBA compatibility (ByVal / ByRef behavior).
(In reply to jferard from comment #7) > The original issue is indeed not a bug. Please close this ticket (I can't). > Feel free to open a new ticket about the VBA compatibility (ByVal / ByRef > behavior). Ok... I'm closing this as NAB. The VBA compatibility issue can be discussed in a separate ticket to avoid confusion.