[futurebasic] Re: [FB] [FB2] XREF Array of Records (lengthy)

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : October 1999 : Group Archive : Group : All Groups

From: Rick Brown <rbrown@...>
Date: Fri, 22 Oct 1999 07:04:38 -0500
Sean wrote:

> >There is a bug in FB2. When you use XREF with records, it creates one
> >extra record to store the length of the array. This is the first record.
> >So it will create an extra 54-byte block just for the 4-byte length of
> >the array. The remaininng 48 bytes go to waste.
> >

Jay replied:

> Sean,
> You'll have to demo this for me--I think you're mistaken. I have used a
> number of XREF's, and I wrote the XREF FAQ and a demo illustrating XREF@
> arrays of records; I have never seen nor heard of this. In fact, I
> believe FB doesn't know or care about the length of the array. It will
> pull down data (?) from any record you request, whether it's part of your
> data block or a megabyte beyond it!
> Maybe you discovered a header block for a handle, which precedes your
> XREF@ array(0) in memory. All handles have these, but you don't need to
> be concerned with them. They are contiguous to, but not part of your
> block.
> OTOH, if _you_ choose to use your 0 record for this purpose, that's your
> prerogative and your responsibility.

There certainly is a (very serious) bug in XREF arrays of records, and it's
been around for years.  But I've never heard it explained in the terms Sean
uses, so I'm not sure if the bug I'm thinking of is the same thing that Sean
is describing.  In my "version" of the bug, you
can crash if you attempt to reference any field in the record except the first
field, in any element of the array.  This bug does NOT exist for XREF@, but
only for XREF.

Here's a demo.  Note that the address of XREFarray.field2%(1) is obviously
bad.  If you un-comment the two commented-out instructions in FN XREFtest, the
program is likely to crash.  In some cases you'll get lucky, and the bad
address you're accessing will by chance not step on anything important (yet). 
In this case your program may not crash, but some other program may crash
later when it needs to access that (now corrupted) memory.

'  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 field1&
  DIM field2%

'===================== 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))
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 lines at your own risk!
  'XREFarray.field2%(1) = 12345
  'PRINT "contents of XREFarray.field2%(1): "; XREFarray.field2%(1)
'===================== main ===================
DIM XREFspace.120
TEXT _geneva, 12
FN NormalTest
FN XREFtest(@XREFspace)
  HANDLEEVENTS      '(loop until command-period)
UNTIL _false