BYREF with incomplete types:

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

BYREF with incomplete types:

Post by angros47 »

The code:

Code: Select all

type UDT_ as UDT  	'forward declaration

declare sub foo(a as UDT_ ptr)

sub foo(a as UDT_ ptr)
end sub
works with no issues. On the other hand, the code:

Code: Select all

type UDT_ as UDT  	'forward declaration

declare sub foo(byref a as UDT_)

sub foo(byref a as UDT_)
end sub
returns "error 71: Incomplete type, before ')' in 'sub foo(byref a as UDT_)'", although the two examples are almost equivalent (in both cases, the whole UDT is not passed to the subroutine).. In theory, the second example should be valid, because I might want to do something like "dim b as UDT_ ptr=@a"

Is there any workaround?
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: BYREF with incomplete types:

Post by caseih »

Usually forward references are only valid in the function declaration. In the implementation of the function, however, the complete type must be known. Which makes sense to me. After all the implementation actually needs to know what the type members are, otherwise why are you passing in the reference?
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: BYREF with incomplete types:

Post by angros47 »

Because I might have something like:

Code: Select all

sub foo overload(a as UDT_ ptr)   
'do stuff
end sub

sub foo(byref a as UDT_)    'an 'alias' to use the variable and not the pointer as argument
foo (@a)
end sub
Also, the first subroutine might be inside a library, and the second in the include file
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: BYREF with incomplete types:

Post by fxm »

angros47 wrote: Aug 31, 2022 22:10 the two examples are almost equivalent (in both cases, the whole UDT is not passed to the subroutine).
But when a variable is passed by reference to a procedure, under the hood a pointer to that variable is passed by value and the compiler always adds (whatever the user procedure body) some hidden code to dereference that pointer so the user can directly use the variable name in the procedure body.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: BYREF with incomplete types:

Post by fxm »

Around your problem

In the following code, the myfoo(Byref u As UDT_)'s procedure body must mandatory put after the UDT definition although it only uses a non dereferenced pointer of its parameter to pass to another procedure:

Code: Select all

Type UDT_ as UDT

Declare Sub foo(Byval As UDT_ Ptr)
Declare Sub myfoo(Byref As UDT_)

'-----------------------------------------------------------------------------

Type UDT
    Dim As String s = "This works!"
End Type

Sub foo(Byval pu As UDT_ Ptr)  '' this procedure body must be mandatory put after the UDT declaration
    Print pu->s
End Sub

Sub myfoo(Byref u As UDT_)  '' but even this other procedure body must be put after the UDT declaration
    foo(@u)
End Sub

'-----------------------------------------------------------------------------

Dim As UDT_ u
myfoo(u)

Sleep

This myfoo(Byref u As UDT_)'s procedure body can be suppressed by only defining a converting procedure pointer instead:

Code: Select all

Type UDT_ as UDT

Declare Sub foo(Byval As UDT_ Ptr)
'Declare Sub myfoo(Byref As UDT_)
Dim As Sub(Byref As UDT_) myfoo = Cast(Sub(Byref As UDT_), @foo)

'-----------------------------------------------------------------------------

Type UDT
    Dim As String s = "This works!"
End Type

Sub foo Overload(Byval pu As UDT_ Ptr)  '' this procedure body must be mandatory put after the UDT declaration
    Print pu->s
End Sub

'Sub myfoo(Byref u As UDT_)  '' but even this other procedure body must be put after the UDT declaration
'    foo(@u)
'End Sub

'-----------------------------------------------------------------------------

Dim As UDT_ u
myfoo(u)

Sleep
Post Reply