More on byref return / byref variable/rvalue type

New to FreeBASIC? Post your questions here.
Post Reply
PeterHu
Posts: 161
Joined: Jul 24, 2022 4:57

More on byref return / byref variable/rvalue type

Post by PeterHu »

I just noticed from the document that FB has provided byref variable and byref return features earlier.The document has explained quite a lot with rich examples.As a slow learner,may I ask is there any more supplements or just some help links (will be best described in fb ,fine in c++ for comparison,for easier understand in fb...) that can help understanding such features,plus,why and how to use them,since I did not noticed there is quite much code making use of these features in fb projects(3rd party libraries).

Thanks in advance.
fxm
Moderator
Posts: 12136
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: More on byref return / byref variable/rvalue type

Post by fxm »

You can also read in the Programmer's Guide:
- From Pointers to References
- Using References
PeterHu
Posts: 161
Joined: Jul 24, 2022 4:57

Re: More on byref return / byref variable/rvalue type

Post by PeterHu »

Yes,I should read over and over on the docs until I thoroughly understand below code.I am wondering under what situation I have to write code like:

Code: Select all

maxRef(i1,i2)=3

Code: Select all

Function maxRef (ByRef r1 As Integer, ByRef r2 As Integer) ByRef As Integer
    If r1 > r2 Then
        Return r1
    Else
        Return r2
  End If
End Function

Dim As Integer i1 = 1, i2 = 2
Print i1, i2
maxRef(i1, i2) = 3
Print i1, i2

Sleep
fxm
Moderator
Posts: 12136
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: More on byref return / byref variable/rvalue type

Post by fxm »

This procedure ('maxRef()') is a bit specific (rather academic) because it produces a different result depending on how it is called (similarly to 'Mid()'):
  • Called like this (as a function):
    x = maxRef(x1, x2)
    it returns the variable with the greatest value between x1 and x2.
  • Called like that (as a statement):
    maxRef(x1, x2) = x
    it assigns, to the largest value between x1 and x2, the new value x.
It is because of this second functionality that the two variables must be passed by reference as well as the return variable.


Simpler example:

Code: Select all

Dim Shared As Integer I

Function equalAssign() Byref As Integer
    Return I
End Function

I = 123
Print equalAssign()
Print I
Print

equalAssign() = 456
Print equalAssign()
Print I

Sleep
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: More on byref return / byref variable/rvalue type

Post by dodicat »

Take the magic out of it, and go back to bare bones pointer.
You are creating a your own return value.

Code: Select all

Function maxRef ( r1 As Integer ptr, r2 As Integer ptr)  As Integer ptr
    If *r1 > *r2 Then
        print "r1"
        Return r1
    Else
        print "r2"
        Return  r2
  End If
End Function

Dim As Integer i1 = 1, i2 = 2
Print i1, i2
print
*maxRef(@i1, @i2) = 3
Print i1, i2
print
print
i1=10:i2=5
*maxRef(@i1, @i2) = 500
Print i1, i2


Sleep 
fxm
Moderator
Posts: 12136
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: More on byref return / byref variable/rvalue type

Post by fxm »

These similar two examples (with pointers or with references) are so described in the 'References versus pointers by comparative examples' paragraph of the 'Using References' documentation page.
fxm
Moderator
Posts: 12136
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: More on byref return / byref variable/rvalue type

Post by fxm »

Note:
When such function (byref return) has only one argument, you need to help the parser to force the assignment instead of the equality operator chosen by default.
To do this, the function return term must be enclosed in parentheses:

Code: Select all

Function equalAssign(Byref x As Integer) Byref As Integer
    Return x
End Function

Dim As Integer I = 123
Print equalAssign(I)
Print I
Print

equalAssign(I) = 456    '' '=' parsed by default as equality operator in function argument
Print equalAssign(I)
Print I
Print

(equalAssign(I)) = 456  '' '=' parsed forced as assignment to BYREF function result
Print equalAssign(I)
Print I

Sleep
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: More on byref return / byref variable/rvalue type

Post by dodicat »

fxm wrote: Feb 05, 2024 12:56 These similar two examples (with pointers or with references) are so described in the 'References versus pointers by comparative examples' paragraph of the 'Using References' documentation page.
Sorry, I didn't know of that example.
I hardly ever use the help docs.
If I need help I just use the F1 key and the cursor in fbide, I have the latest .chm tagged to fbide.
I never go any further than that, maybe I should of course.
PeterHu
Posts: 161
Joined: Jul 24, 2022 4:57

Re: More on byref return / byref variable/rvalue type

Post by PeterHu »

Thank you two gentlemen.Really really helps a lot,especially the pointer versions provided by both of you help me better understanding how reference variable works(looks like) internally.

I am not so confident to say I have thoroughly understood.I need to think over (*variable) <---> (byRef variable),what is the same part and what is the different part.
fxm
Moderator
Posts: 12136
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: More on byref return / byref variable/rvalue type

Post by fxm »

PeterHu wrote: Feb 06, 2024 1:12 I am not so confident to say I have thoroughly understood.I need to think over (*variable) <---> (byRef variable),what is the same part and what is the different part.

1. For code body, there is an equivalence between using dereferenced pointer and using reference

Code: Select all

Dim As Integer I = 1

Dim As Integer Ptr pI = @I
Print *pI
*pI = 2
Print *pI
Print

Dim Byref As Integer rI = I
Print rI
rI = 3
Print rI

Sleep

2. For procedure calling, there is an equivalence between passing/returning 'Byval As type Ptr' and passing/returning 'Byref As type'
  • Example with a procedure passing/returning 'Byval As Integer Ptr' and a procedure pointer to this procedure but declared passing/returning 'Byref As Integer':

    Code: Select all

    Function maxPtr (ByVal p1 As Integer Ptr, ByVal p2 As Integer Ptr) As Integer Ptr
        If *p1 > *p2 Then
            Return p1
        Else
            Return p2
        End If
    End Function
    
    Dim maxRef As Function (ByRef As Integer, Byref As Integer) Byref As Integer = Cast(Any Ptr, @maxPtr)
    
    Dim As Integer i1 = 1, i2 = 2
    
    Print i1, i2
    Print maxRef(i1, i2)
    Print
    
    maxRef(i1, i2) = 3
    Print i1, i2
    Print maxRef(i1, i2)
    
    Sleep
    
  • Example with a procedure passing/returning 'Byref As Integer' and a procedure pointer to this procedure but declared passing/returning 'Byval As Integer Ptr':

    Code: Select all

    Function maxRef (ByRef r1 As Integer, ByRef r2 As Integer) ByRef As Integer
        If r1 > r2 Then
            Return r1
        Else
            Return r2
        End If
    End Function
    
    Dim maxPtr As Function (ByVal As Integer Ptr, ByVal As Integer Ptr) As Integer Ptr = Cast(Any Ptr, @maxRef)
    
    Dim As Integer i1 = 1, i2 = 2
    
    Print i1, i2
    Print *maxPtr(@i1, @i2)
    Print
    
    *maxPtr(@i1, @i2) = 3
    Print i1, i2
    Print *maxPtr(@i1, @i2)
    
    Sleep
    
PeterHu
Posts: 161
Joined: Jul 24, 2022 4:57

Re: More on byref return / byref variable/rvalue type

Post by PeterHu »

fxm wrote: Feb 06, 2024 12:20
PeterHu wrote: Feb 06, 2024 1:12 I am not so confident to say I have thoroughly understood.I need to think over (*variable) <---> (byRef variable),what is the same part and what is the different part.

1. For code body, there is an equivalence between using dereferenced pointer and using reference

Code: Select all

Dim As Integer I = 1

Dim As Integer Ptr pI = @I
Print *pI
*pI = 2
Print *pI
Print

Dim Byref As Integer rI = I
Print rI
rI = 3
Print rI

Sleep

2. For procedure calling, there is an equivalence between passing/returning 'Byval As type Ptr' and passing/returning 'Byref As type'
  • Example with a procedure passing/returning 'Byval As Integer Ptr' and a procedure pointer to this procedure but declared passing/returning 'Byref As Integer':

    Code: Select all

    Function maxPtr (ByVal p1 As Integer Ptr, ByVal p2 As Integer Ptr) As Integer Ptr
        If *p1 > *p2 Then
            Return p1
        Else
            Return p2
        End If
    End Function
    
    Dim maxRef As Function (ByRef As Integer, Byref As Integer) Byref As Integer = Cast(Any Ptr, @maxPtr)
    
    Dim As Integer i1 = 1, i2 = 2
    
    Print i1, i2
    Print maxRef(i1, i2)
    Print
    
    maxRef(i1, i2) = 3
    Print i1, i2
    Print maxRef(i1, i2)
    
    Sleep
    
  • Example with a procedure passing/returning 'Byref As Integer' and a procedure pointer to this procedure but declared passing/returning 'Byval As Integer Ptr':

    Code: Select all

    Function maxRef (ByRef r1 As Integer, ByRef r2 As Integer) ByRef As Integer
        If r1 > r2 Then
            Return r1
        Else
            Return r2
        End If
    End Function
    
    Dim maxPtr As Function (ByVal As Integer Ptr, ByVal As Integer Ptr) As Integer Ptr = Cast(Any Ptr, @maxRef)
    
    Dim As Integer i1 = 1, i2 = 2
    
    Print i1, i2
    Print *maxPtr(@i1, @i2)
    Print
    
    *maxPtr(@i1, @i2) = 3
    Print i1, i2
    Print *maxPtr(@i1, @i2)
    
    Sleep
    
Appreciated!
Post Reply