FB II Compiler

PG PRO

Debugging

Memory

System

Mathematics

Resources

Disk I/O

Windows

Controls

Menus

Mouse

Keyboard

Text

Fonts

Drawing

Sound

Clipboard

Printing

Communication

ASM

Made with FB

FB II COMPILER

Work around the XREF bug


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