Dim Byref syntax

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim Byref syntax

Post by fxm »

Depending on the code example, one gets a runtime error, either at compilation (like yours) or at execution.

In your example, the syntax 'Dim Shared ByRef aU_SeN As ini = aIn(0)' should be forbidden by the compiler, because @aIn(0) is not constant when the array is dynamic.

One should get a similar compiler error than for this last code line:

Code: Select all

Dim Shared As Integer s_array(10)
Redim Shared As Integer d_array(10)

Dim Shared As Integer Ptr s_p = @s_array(0)
Dim Shared As Integer Ptr d_p = @d_array(0)
Compiler output:
.....\FBIde0.4.6r4_fbc1.06.0\FBIDETEMP.bas(5) error 11: Expected constant in 'Dim Shared As Integer Ptr d_p = @d_array(0)'

Perhaps reuse the code error "320 Incompatible reference initializer".
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim Byref syntax

Post by fxm »

@dkl

About the above problem:
- A declaration of a global reference cannot have an initialiser assigning an element of a global dynamic structure like an array.
- This should not be allowed by the compiler.
- This now induces only a runtime error at compilation time or at execution time.

The support for dim'ing references being still in progress, must I fill a bug report on the above problem or will you keep that in mind for the continuation of this further development?
Last edited by fxm on Feb 20, 2016 9:17, edited 3 times in total.
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: Dim Byref syntax

Post by dafhi »

I'm glad for your clever eye, fxm!
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Dim Byref syntax

Post by dkl »

Hi fxm,

for any bugs, I think it's best to create a bug report, if it's not fixed within 1 day. The bug report ensures that the issue will be seen and won't get lost, in case it couldn't be solved immediately.

It's fine to report bugs even in the development version, and even more so for released features like Dim Byref.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim Byref syntax

Post by fxm »

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

Re: Dim Byref syntax

Post by fxm »

Compiler aborts when initializing a static byref member UDT with a local instance

The compiler outputs the normal error message, then aborts after:

Code: Select all

Type UDT1
  Dim As Integer I1
End Type

Type UDT2
  Dim As Integer I2
  Static Byref As UDT1 ru1
End Type

Dim As UDT1 u1

Dim Byref As UDT1 UDT2.ru1 = u1
Compiler output:
.....\FBIde0.4.6r4_fbc1.06.0\FBIDETEMP.bas(12) error 271: Local symbols can't be referenced in 'Dim Byref As UDT1 UDT2.ru1 = u1'
Aborting due to runtime error 12 ("segmentation violation" signal)

If we replace:
Dim As UDT1 u1
with:
Static As UDT1 u1
=> only the normal error message (without aborting)

For simpler static byref variables, the error is well outputted and compilation ends normally.


Remark:

- A compiler aborting is directly obtained if the static byref member UDT is initialized with a dereferenced null pointer:

Code: Select all

Type UDT1
  Dim As Integer I1
End Type

Type UDT2
  Dim As Integer I2
  Static Byref As UDT1 ru1
End Type

Dim Byref As UDT1 UDT2.ru1 = *Cast(UDT1 Ptr, 0)
Compiler output:
Aborting due to runtime error 12 ("segmentation violation" signal)

- While this syntax works for simpler static byref variables:

Code: Select all

Type UDT
  Dim As Integer I
  Static Byref As Integer RI
End Type

Dim Byref As Integer UDT.RI = *Cast(Integer Ptr, 0)
Results:
Compilation successful


Other remark:
In Win 64-bits, the compiler hangs without any error message.


[edit] (Apr 06, 2016)
Bug report filled:
#822 Compiler aborts when initializing a static byref member UDT with a local instance
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim Byref syntax

Post by fxm »

It's a shame that the preview button has been suppressed when creating a ticket.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Dim Byref syntax

Post by Tourist Trap »

Hi,
playing around with the stuff in this recent topic: http://www.freebasic.net/forum/viewtopi ... 23#p226123, I've tried to work around a case discussed there with fxm.

I've found that below that I don't understand:

Code: Select all

type X extends OBJECT
    static as const  integer  y
end type
dim as const integer   X.y = 0

function XXX() as const integer static
   dim as const integer v = X.y
   var byref u = v
   
   return u
end function
Despite of the rather special aspect of this, there is only one compiler issue, the value X.y is not accepted as a constant.
It's surprising because it has been declared as a constant. Or do I miss something obvious?

As a reminder, here is the problem initially encountered leading to this above.

Code: Select all

type X extends OBJECT
   static as const integer   y
end type
dim as const integer X.y = 0

function XXX() byref as const integer static
      var byref u = *cast(integer ptr, @X.y)
      return u
end function

? XXX()
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim Byref syntax

Post by fxm »

More simply/generally, the following code is not allowed:

Code: Select all

Static As Integer I = 0
Static As Integer J = I
Even if "I" was declared as "Static As Const Integer I = 123", "123" is well a constant but the value of "I" is not a constant.

By cons, about the second example, "@X.y" is well a constant because "y" is a static field, but the good code is:

Code: Select all

type X extends OBJECT
   static as const integer   y
end type
dim as const integer X.y = 123

function XXX() byref as const integer static
      var byref u = *cast(const integer ptr, @X.y)  '' or simply: var byref u = X.y
      return u
end function

? XXX()
With a similar bad code using a dereferenced pointer instead of reference, the compiler error is well outputted:

Code: Select all

type X extends OBJECT
   static as const integer   y
end type
dim as const integer X.y = 123

function XXX() byref as const integer static
      'var byref u = *cast(integer ptr, @X.y)
      'return u
      var pu = cast(integer ptr, @X.y)
      return *pu
end function

? XXX()
error 11: Expected constant in 'var pu = cast(integer ptr, @X.y)'
Another case where Byref (variable) does not exit the assignment error of its internal pointer (which remains null)
Last edited by fxm on Nov 11, 2016 14:27, edited 1 time in total.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim Byref syntax

Post by fxm »

coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Dim Byref syntax

Post by coderJeff »

From viewtopic.php?p=248410#p248410
fxm wrote:
coderJeff wrote:With dkl's work on BYREF variables, and BYREF function returns, not using pointers is also appealing. I find that using BYREF and . DOT member access tends to make the code a little easier to read and don't have to worry about @, *, -> operators.
I fully agree.
It's why I'm waiting impatiently the continuing of development around references:
- adding the capacity to define arrays (static or dynamic) of references,
- adding the capacity to declare member references (variables and arrays) in UDTs,
so that they can also replace the use of pointers in these cases.

Don't forget the still open bug reports:
- #814 A global reference declaration cannot have an initializer which assigns an element of a global dynamic array
- #822 Compiler aborts when initializing a static byref member UDT with a local instance
- #842 BYREF (variable) does not report some assignment errors detectable on its internal pointer
I've been looking at these bugs, and wanted to continue the discussion here. For me, if fbc crashes, or fbc generates bad code and crashes, that becomes a high priority bug to fix. I know there is a number of posts in this threads regarding objects, first I just want to focus on the simple stuff like:

Code: Select all

	'' shared references
	dim shared a as integer = 5
	dim shared byref as integer b = a
	dim shared byref as integer c = a
	dim shared byref as integer d = a
versus:

Code: Select all

	'' shared references to references
	dim shared a as integer = 5
	dim shared byref as integer b = a
	dim shared byref as integer c = b '' SEGFAULT
	dim shared byref as integer d = c '' SEGFAULT
A few thoughts: I think I am fairly skilled in C so I I think understand pointers very well. The byref syntax in C++, I never used much; I can explain it terms of pointers, but when I look through the fbc compiler source code, there are many places that handle references specifically. So I also understand that can't quite explain references as "it's just like a pointer but...."
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim Byref syntax

Post by fxm »

Since the discussion seems to be revived, I would like here to give my opinion again about the further development (see my request above).

In its current implementation in FB, a reference can be re-initialized to refer to another object (but of compatible type), and that like few other languages and unlike many other languages, but I agree to keep as much flexibility as with pointers.
Presently, a reference can also be re-initialized to refer to nothing, a "null" reference (@ref = 0), and this can be done even at the level of its declaration:

Code: Select all

Dim As Integer i1, i2

Dim Byref As Integer ref1 = i1

'' reference re-initialized
@ref1 = @i2

'' reference re-initialized to a "null" reference
@ref1 = 0

'' reference directly initialized to a "null" reference at declaration level
Dim Byref As Integer ref2 = *Cptr(Integer Ptr, 0)
Presently one can also pass/return to/from a procedure a "null" reference by using '*Cptr(datatype Ptr, 0)', or even the short-cut syntax 'Byval 0'.

I would even be in favor of possibility of declaring more simply a "null" reference (@ref = 0) by authorizing a declaration without any initializer:
'Dim Byref As datatype ref'
This would simplify the further development to be able to:
- declare a reference as a UDT member,
- declare a dynamic array of references.

Additional functionality to implement for consistency with the authorization of a "null" reference:
- add the null-pointer check on the internal pointer of the reference when compiling with the '-exx' option.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Dim Byref syntax

Post by dkl »

For this case:

Code: Select all

dim shared a as integer = 5
dim shared byref as integer b = a
dim shared byref as integer c = b '' fbc crash

print a, b, c
src/compiler/ast-node-typeini.bas(550): assertion failed at HFLUSHEXPRSTATIC: (expr->class =AST_NODECLASS_CONST)
the problem in fbc is that hCheckAndBuildByrefInitializer() produces a non-constant initializer for the c pointer (it just tries to copy the pointer value from the b pointer), so hFlushExprStatic() hits the assert().

a is a global var, initialized with a constant, which works.
b internally is a global pointer, initialized with the address ("offset") of a, that's "constant" enough and it works.
c internally is a global pointer, initialized with the value of b, that's non-constant and can't work.

So either hCheckAndBuildByrefInitializer() must disallow the 3rd case, or fbc has to generate code in a global constructor to do the initialization. Or I guess if fbc was smart enough it could notice that b's value is actually a constant initializer and just duplicate that.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Dim Byref syntax

Post by coderJeff »

dkl wrote:Or I guess if fbc was smart enough it could notice that b's value is actually a constant initializer and just duplicate that.
That's exactly what I've been trying to do in hFlushExprStatic(). If it's a reference var, look at the initree to get the actual value to initialize, looping through a chain of references, if needed. If end result is not const then error. My efforts are slow going as I learn this part of the code.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Dim Byref syntax

Post by dkl »

Here's a fix that adds the missing initializer validation (disallow non-constant initializers): https://github.com/freebasic/fbc/pull/87

I think allowing initialization of a global ref from another ref by duplicating the other's initree is possible, and should be done in hCheckAndBuildByrefInitializer() before the validation checks, so that the new initree will also be checked. Although it's kind of pointless to check it twice, the point is to check that it's duplicated correctly. Also, doing it early ensures that the first initree is still available (at time of hFlushExprStatic(), it may be too late, because the 1st one may already have been emitted and destroyed).
Post Reply