Bug 150727 - A reference passed as parameter gets a new target
Summary: A reference passed as parameter gets a new target
Status: RESOLVED NOTABUG
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: BASIC (show other bugs)
Version:
(earliest affected)
7.3.5.2 release
Hardware: x86-64 (AMD64) Linux (All)
: medium minor
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-08-31 16:38 UTC by jferard
Modified: 2022-09-16 18:29 UTC (History)
2 users (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jferard 2022-08-31 16:38:53 UTC
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
Comment 1 Rafael Lima 2022-08-31 18:02:58 UTC
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.
Comment 2 jferard 2022-08-31 20:09:46 UTC
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".
Comment 3 Rafael Lima 2022-08-31 20:31:40 UTC
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
Comment 4 jcsanz 2022-08-31 20:37:44 UTC
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"
Comment 5 jferard 2022-08-31 21:10:16 UTC
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).
Comment 6 Mike Kaganski 2022-08-31 21:15:57 UTC
(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.
Comment 7 jferard 2022-09-16 16:43:19 UTC
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).
Comment 8 Rafael Lima 2022-09-16 18:15:04 UTC
(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.