## How to Use the Lbound / Ubound Size information of Array in FB

Forum for discussion about the documentation project.
fxm
Posts: 8175
Joined: Apr 22, 2009 12:46
Location: Paris suburb, FRANCE

### How to Use the Lbound / Ubound Size information of Array in FB

LBound / UBound returns the lower / upper values of size information for an array: the dimension of the array (number of usable indexes) and the index bounds for each dimension. The array name is specified in the first parameter, and the dimension selection in the second parameter.
These sizing information are available both for a fixed-length array (sizing fixed at compile-time) and for a variable-length array (some sizing adjustable during run-time).

1) Usage:
result = [L|U]Bound( array [, dimension ] )
with as parameters:
array : array name, without parentheses
dimension : dimension number to get the bound, ordered from left to right compared to index position when accessing array
(1 = first dimension)
2) Return value:
For the specific dimension value '0':
LBound returns always '1', and UBound returns the number of dimensions
if the array is not fully sized (declared as 'array( )' or 'array( Any [, Any...] )'), UBound returns '0'
For any valid dimension value of the array (from 1 to the last one):
[L|U]Bound returns the lowest|highest value that can be used as an index for the specified dimension
if the array is not fully sized (declared as 'array( )' or 'array( Any [, Any...] )'), LBound returns '0' and UBound returns '-1'
For any other dimension value (dimension number not relevant):
LBound returns always '0', and UBound returns always '-1'
Summarizing table example:

Code: Select all

`Array definition |      array( )       | array( Any , Any )  | array( 4 , 5 To 9 ) |Dimension nb (x) |                     |        (1)   (2)    |       (1)    (2)    |-----------------|---------------------|---------------------|---------------------|Lbound(array, 0) |      1              |      1              |      1              |Ubound(array, 0) |      0              |      0 (but not 2!) |      2              |-----------------|---------------------|---------------------|---------------------|Lbound(array, 1) |      0              |      0              |      0 (by default) |Ubound(array, 1) |     -1              |     -1              |      4              |-----------------|---------------------|---------------------|---------------------|Lbound(array, 2) |      0              |      0              |      5              |Ubound(array, 2) |     -1              |     -1              |      9              |-----------------|---------------------|---------------------|---------------------|Lbound(array, k) |      0              |      0              |      0              |Ubound(array, k) |     -1              |     -1              |     -1              |  for k<0 or k>2 |                     |                     |                     |-----------------|---------------------|---------------------|---------------------|`

3) Use cases:
So UBound( array , 0 ) value allows to easily determine if an array is sized (value > 0) or not (value = 0), and if yes the number of dimensions (the positive value).
Remark: ( ( LBound( array ) = 0 ) AND ( UBound( array ) = -1 ) ) Or ( @array( LBound( array ) ) = 0 ) would allow to only know that the array is un-sized.
Once the number of dimensions is determined, the information on the two boundaries of each dimension is safely accessible.

Example of a macro that displays all the sizing information for an array:

Code: Select all

`#macro PRINT_ARRAY_SIZING (array)  If UBound( array , 0 ) = 0 Then    Print "'" & #array & "' un-sized"  Else    Print "'" & #array & "' sized with " & UBound( array , 0 ) & " dimension";    If UBound( array , 0 ) > 1 Then      Print "s";    End If    Print    For I As Integer = 1 To UBound( array , 0 )      Print "   dimension nb: " & I      Print "      lower bound: " & LBound( array , I )      Print "      upper bound: " & UBound( array , I )    Next I  End If#endmacroDim As Integer array1( )PRINT_ARRAY_SIZING( array1 )PrintDim As Single array2( Any )PRINT_ARRAY_SIZING( array2 )PrintDim As String array3( 4 , 5 To 9 )PRINT_ARRAY_SIZING( array3 )PrintType UDT  Dim As Double array4( Any, Any, Any )End TypeDim As UDT uPRINT_ARRAY_SIZING( u.array4 )PrintRedim u.array4( -7 to -3, -2 To 5, 6 To 9 )PRINT_ARRAY_SIZING( u.array4 )PrintErase u.array4PRINT_ARRAY_SIZING( u.array4 )PrintSleep`
Output:

Code: Select all

`'array1' un-sized'array2' un-sized'array3' sized with 2 dimensions   dimension nb: 1      lower bound: 0      upper bound: 4   dimension nb: 2      lower bound: 5      upper bound: 9'u.array4' un-sized'u.array4' sized with 3 dimensions   dimension nb: 1      lower bound: -7      upper bound: -3   dimension nb: 2      lower bound: -2      upper bound: 5   dimension nb: 3      lower bound: 6      upper bound: 9'u.array4' un-sized`
4) Notes:
The maximum number of dimensions of a multidimensional array is 8.

At the contrary to QB, FB stores the multidimensional arrays data in this definite order: values differing only in the last index are contiguous in memory (row-major order).

An array declared with 'Any' instead of the bound fields is considered presently to be fully un-sized from UBound (UBound( array , 0 ) = 0), while at least its number of dimensions is already fixed (and locked) .
Moreover this value of the number of dimensions is well set in the array descriptor.
In this case, UBound( array , 0 ) could return this value while remaining with LBound (array , 0 ) = 0 and UBound( array , 0 ) = -1.