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

Forum for discussion about the documentation project.
Post Reply
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

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

Post by fxm »

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.
    A bug report has already been filled in, about this behavior:
    #853 'Ubound(array, 0)' does not work with array defined by 'Dim array(Any [, Any...])'
Post Reply