[futurebasic] Re: XREF question

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

From: Rick Brown <rbrown@...>
Date: Sat, 28 Mar 1998 10:55:36 -0600
Joe wrote:
> I don't quite understand XREF and I hope some one can give me some tips. As I
> understand XREF allows you to use a Pointer as an array of any kind of
> variable. Can you XREF an array of records too? 

Technically you can, but you have to be careful when you do this,
because of a long-standing bug in FB that can crash your program.  The
details of the bug are:

If you declare an array of records using XREF, like so:

  XREF myArray.myRecSize(_maxElements)

and then you attempt to access any individual field _except_ the first,
in any element in the array, like so:

  z& = myArray.field2&(14)  '(say field2& is the 2nd field)

then you'll almost certainly crash.  The way around this is: whenever
you want to work with an element of the array, copy it to a "scratch"
record first:

  DIM scratch.myRecSize
  scratch = myArray(14)
  z& = scratch.field2&

Likewise, instead of doing this:

  myArray.field1%(14) = x
  myArray.field2&(14) = z&

do this:

  scratch.field1% = x
  scracth.field2& = z&
  myArray(14) = scratch

> Also when I use a variable as the argument in the XREF command like this: XREF
> Array%(numInArray), FutureBasic gives me this confusing error message: "DIM
> requires numbers or constants when defining an array. Use XREF instead of DIM
> if the array is dynamic."

Yes, that's a confusing message.  It probably should say something like:
"Array dimensions in a DIM or XREF statement must be literal or symbolic
integer constants."

> I have been getting around this by using a constant larger than I think I will
> ever need as the XREF argument.

Actually, you can use the number "1" and it will work just as well.  In
a DIM statement, FB uses the number in parentheses to determine how much
storage space to allocate.  But in an XREF statement, the storage space
is allocated elsewhere (wherever you defined the block that your pointer
points to), so FB basically ignores the value of the dimension in the
XREF statement.

...at least that's the case for 1-dimensional arrays.  If your XREF
array has more than 1 dimension, then FB needs to know the correct max
values for the 2nd, 3rd, etc. dimensions, so that it can tell (for
example) how far the offset is between myArray(0,0,0) and
myArray(3,2,9).

But if the array is 1-dimensional, FB can calculate the offset between,
say, myArray(0) and myArray(37) just by knowing the record size.  So in
that case, the dimension value in the XREF statement is irrelevant.

- Rick