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

Forum for discussion about the documentation project.
fxm
Posts: 8699
Joined: Apr 22, 2009 12:46
Location: Paris (suburbs), 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
#endmacro

Dim As Integer array1( )
PRINT_ARRAY_SIZING( array1 )
Print

Dim As Single array2( Any )
PRINT_ARRAY_SIZING( array2 )
Print

Dim As String array3( 4 , 5 To 9 )
PRINT_ARRAY_SIZING( array3 )
Print

Type UDT
Dim As Double array4( Any, Any, Any )
End Type

Dim As UDT u
PRINT_ARRAY_SIZING( u.array4 )
Print

Redim u.array4( -7 to -3, -2 To 5, 6 To 9 )
PRINT_ARRAY_SIZING( u.array4 )
Print

Erase u.array4
PRINT_ARRAY_SIZING( u.array4 )
Print

Sleep
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.