Bug? byval vs byref

tkristensen

Member
Licensed User
Longtime User
Erel,

We've hit our heads on this one quite a lot lately. It seems that when you set one type structure to the value of another duplicate structure the code actually does it by reference rather than by value. So if you subsequently change an element of the copied from object the copies to object changes as well somewhat unintuitively.

Sample code
B4X:
First the type

Type VQ (FilePath As String, FileName As String, FileType As Int, QuestionNo, AnswerNo As Int) 
    Type VideoQ (NumberQueued As Int, Q(20) As VQ)
    Dim VideoQueue As VideoQ
    VideoQueue.Initialize

now the subs

Sub QueueVideo(VideoPath As String, VideoName As String, VideoType As Int, QuestionNo As Int, AnswerNo As Int)

    Dim Q As Int = VideoQueue.NumberQueued
    If Q < 20 Then
        If VideoQueue.Q(Q).IsInitialized = False Then
            VideoQueue.Q(Q).Initialize
        End If
        VideoQueue.Q(Q).FilePath = VideoPath
        VideoQueue.Q(Q).FileName = VideoName
        VideoQueue.Q(Q).FileType = VideoType
        VideoQueue.Q(Q).QuestionNo = QuestionNo
        VideoQueue.Q(Q).AnswerNo = AnswerNo
        VideoQueue.NumberQueued = Q + 1
    End If

    If VideoQueue.NumberQueued = 1 Then
        PlayVideo(VideoQueue.Q(0).FilePath,
    End If
End Sub

Sub UnQueueVideo

    VideoQueue.Q(0).Initialize                    'Clear level 0 queue

    Dim i As Int = 0
    For i = 1 To VideoQueue.Q.Length - 1
        If VideoQueue.Q(i).IsInitialized Then
            VideoQueue.Q(i -1) = VideoQueue.Q(i)
        Else

            VideoQueue.Q(i-1).Initialize
            Exit
        End If
    Next

    VideoQueue.NumberQueued = VideoQueue.NumberQueued - 1
    If VideoQueue.NumberQueued < 0 Then VideoQueue.NumberQueued = 0
End Sub

This version of the UnQueueVideo routine does NOT work. What it does on the line:

VideoQueue.Q(i -1) = VideoQueue.Q(i)

is to set videoqueue.q(i-1) to a reference (rather than value) of videoqueue.q(i). Because of this when you initialize the higher queue number on the following pass it will also initialize the i-1 object.

The following Does work:

B4X:
Sub UnQueueVideo

   VideoQueue.Q(0).Initialize           'Clear level 0 queue

   Dim i As Int = 0
   For i = 1 To VideoQueue.Q.Length - 1
     If VideoQueue.Q(i).IsInitialized Then
       VideoQueue.Q(i - 1).AnswerNo = VideoQueue.Q(i).AnswerNo
       VideoQueue.Q(i - 1).FileName = VideoQueue.Q(i).FileName
       VideoQueue.Q(i - 1).FilePath  = VideoQueue.Q(i).FilePath  
       VideoQueue.Q(i - 1).FileType  = VideoQueue.Q(i).FileType
       VideoQueue.Q(i - 1).QuestionNo  = VideoQueue.Q(i).QuestionNo  
     Else
       VideoQueue.Q(i-1).Initialize
       Exit
     End If
   Next
   VideoQueue.NumberQueued = VideoQueue.NumberQueued - 1
   If VideoQueue.NumberQueued < 0 Then VideoQueue.NumberQueued = 0
End Sub

I guess my question is, is this intentional?

Thanks in advance

Tom
 
Top