[futurebasic] Re: [FB] Using XREF@ [COORD]

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : November 1998 : Group Archive : Group : All Groups

From: Rick Brown <rbrown@...>
Date: Sun, 29 Nov 1998 09:23:22 -0600
> There's been a good thread going on XREFs now.

Here's the nature of the XREF bug, for the benefit of the XREF FAQ (also
might cross reference this in the "known bugs" FAQ):

Description:
------------
The bug appears when you have an XREF array of _records_.  If your
program tries to access any "field" except the first, in any element of
such an array, FB does not correctly calculate the field's address.  At
best this will give you wrong results whenever you try to read or write
such a field; at worst, it will crash your system.

If you access only the first field in the record, or you access the
entire record as a whole, there seems to be no problem.  Also, the bug
exists for "XREF", but not for "XREF@".

Demo:
-----
The following code demonstrates the bug.  If you un-comment the
commented line in FN XREFtest, you will get an even better
demonstration--your system will probably crash!

'=============================================
'  This demo illustrates a problem with
'  the way XREF arrays are used.  Specifically,
'  if XREF defines an array of records, then
'  FB does not correctly calculate the address
'  of a field within a particular array element
'  unless it happens to be the first field
'  of the record structure.  More often than
'  not, a system error will result if an
'  attempt is made to actually access the contents
'  of such a field.
'=============================================
COMPILE 0, _caseInsensitive

DIM RECORD myRecord
  DIM field1&
  DIM field2%
DIM END RECORD _myRecord

END GLOBALS
'===================== functions ==============
LOCAL FN NormalTest
  DIM normalArray.myRecord(20)
  PRINT "normalArray(1) is at: "; VARPTR(normalArray(1))
  PRINT "normalArray.field1&(1) is at: "; VARPTR(normalArray.field1&(1))
  PRINT "normalArray.field2%(1) is at: "; VARPTR(normalArray.field2%(1))
  PRINT "normalArray(2) is at: "; VARPTR(normalArray(2))
END FN
'----------------------------------------------
LOCAL FN XREFtest(addr&)
  XREFarray& = addr&
  XREF XREFarray.myRecord(20)
  PRINT "XREFarray(1) is at: "; VARPTR(XREFarray(1))
  PRINT "XREFarray.field1&(1) is at: "; VARPTR(XREFarray.field1&(1))
  PRINT "XREFarray.field2%(1) is at: "; VARPTR(XREFarray.field2%(1))
  PRINT "XREFarray(2) is at: "; VARPTR(XREFarray(2))
  'Un-comment the following line at your own risk!
  'PRINT "contents of XREFarray.field2%(1): "; XREFarray.field2%(1)
END FN
'===================== main ===================
DIM XREFspace.120
WINDOW 1
TEXT _geneva, 12
CLS
FN NormalTest
PRINT
FN XREFtest(@XREFspace)
DO
  HANDLEEVENTS  '(loop until command-period)
UNTIL _false
END


Workaround:
-----------
One way to work around this problem is to always use a local record
variable when working with a record's individual fields.  For example:

XREF recArray.myRecord
DIM localVar.myRecord
FOR i = 1 to n
  localVar = recArray(1)
  '--(read and/or write fields in localVar)
  recArray(1) = localVar
NEXT

---------------------

- Rick