Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
getting the number of dimensions in an array on the fly?
#1
Google suggested the "error trapping" method (see below). 

Is that how we do it in QB64PE? 

Quote:In QB64PE, there is no direct function or property to determine the number of dimensions of an array at runtime, unlike some other languages.
However, you can achieve this by attempting to access UBOUND with increasing dimension indices and handling the ON ERROR condition.

Here's a method using ON ERROR:

Code: (Select All)
DIM a(2, 2, 2) AS INTEGER ' Example: a 3-dimensional array
DIM SHARED numDimensions AS INTEGER

ON ERROR GOTO ErrorHandler

CALL CountDimensions(a())

PRINT "Number of dimensions: "; numDimensions

END

ErrorHandler:
    IF ERR = 9 THEN ' Subscript out of range error
        RESUME NEXT ' Continue execution after the error
    ELSE
        PRINT "An unexpected error occurred: "; ERR
        END
    END IF

SUB CountDimensions (arr() AS INTEGER)
    numDimensions = 0
    DO
        numDimensions = numDimensions + 1
        ' Attempt to get the upper bound of the current dimension
        ' If this dimension doesn't exist, an error will occur
        dummy = UBOUND(arr, numDimensions)
    LOOP
END SUB

Explanation:

DIM SHARED numDimensions AS INTEGER:
Declares a shared variable to store the count of dimensions, accessible by the CountDimensions sub-procedure.

ON ERROR GOTO ErrorHandler:
Sets up error handling. If an error occurs, the program jumps to the ErrorHandler label.

CALL CountDimensions(a()):
Calls the sub-procedure to determine the dimensions, passing the array.

SUB CountDimensions (arr() AS INTEGER):
Initializes numDimensions to 0.

The DO...LOOP attempts to get the UBOUND of progressively higher dimensions (UBOUND(arr, 1), UBOUND(arr, 2), etc.).

If UBOUND is called with a dimension index that doesn't exist, a "Subscript out of range" error (error code 9) will occur.

ErrorHandler::
Checks if the error is "Subscript out of range" (ERR = 9).

If it is, RESUME NEXT is used to continue execution from the statement immediately following the one that caused the error (which is the dummy = UBOUND(...) line). This effectively stops incrementing numDimensions at the correct value.

If it's a different error, it prints the error code and ends the program.

This method leverages QB64PE's error handling to indirectly determine the number of dimensions by detecting when an invalid dimension index is accessed.
Reply
#2
We have to dim the arrays, so...

Dim a(2, 3, 4) As Integer ' Example: a 3-dimensional array
Print UBound(a)
Print UBound(a, 2)
Print UBound(a, 3)

Results:
2
3
4

So using ubound gets the indicies at runtime. What are you looking to use this for?

I mean if you don't do a dim, you just get the default 10 value...

a(1, 1, 1) = 500
Print UBound(a)
Print UBound(a, 2)
Print UBound(a, 3)

Results:
10
10
10

I think what you are getting at is how to determine if the array is multidimensional. Yeah, the Google code should be...

Code: (Select All)
Dim a(2, 3, 4) As Integer ' Example: a 3-dimensional array
Print UBound(a)
Print UBound(a, 2)
Print UBound(a, 3)
Dim Shared numDimensions As Integer

On Error GoTo ErrorHandler

Call CountDimensions(a())

End

ErrorHandler:
If Err = 9 Then ' Subscript out of range error
    End
Else
    Print "An unexpected error occurred: "; Err
    End
End If

Sub CountDimensions (arr() As Integer)
    numDimensions = 0
    Do
        numDimensions = numDimensions + 1
        ' Attempt to get the upper bound of the current dimension
        ' If this dimension doesn't exist, an error will occur
        dummy = UBound(arr, numDimensions)
        Print "dummy ="; dummy
    Loop
End Sub

I suppose a way around it is to just assign variables to the array, and track tose instead of doing an error trap...

Code: (Select All)
Dim Shared As Integer d1, d2, d3
d1 = 2: d2 = 3
Dim a(d1, d2) As Integer ' Example: a 3-dimensional array

Print "UBound Indicies #1 ="; d1;: If d1 Then Print UBound(a, 1) Else Print
Print "UBound Indicies #2 ="; d2;: If d2 Then Print UBound(a, 2) Else Print
Print "UBound Indicies #3 ="; d3;: If d3 Then Print UBound(a, 3) Else Print

And maybe I just missed the point entirely. Let me know if that's the case, but this is where my old tired mind wondered off to... and now if you will excuse me, I have my foot caught in a rabbit hole!

Pete
Reply
#3
No, good sir, I think you got it. Is an array 1-dimensional, 2 or 3? 

I have a case where an array is passed in and it could be any of those.

I guess the simplest way to tell (for now) is the On Error method. 

As you say, we could reserve the first element of the first dimension of all arrays to hold that info, although that would make more work having to modify all routines that return arrays, and also be harder to understand later on for someone else reading the code. 

Thanks for lending your brain to this!
Reply
#4
ChatGPT (or Google or whatever) was close, but you need an exit condition in there:

Code: (Select All)
Dim a(2, 2, 2) As Integer ' Example: a 3-dimensional array
On Error GoTo ErrorHandler

Print "Number of dimensions: "; CountDimensions(a())
End

ErrorHandler:
If Err = 9 Then ' Subscript out of range error
    exitcount = _TRUE
    Resume Next ' Continue execution after the error
Else
    Print "An unexpected error occurred: "; Err
    End
End If

Function CountDimensions (arr() As Integer)
    Shared exitcount
    exitcount = _FALSE
    Do
        numDimensions = numDimensions + 1
        ' Attempt to get the upper bound of the current dimension
        ' If this dimension doesn't exist, an error will occur
        dummy = UBound(arr, numDimensions)
    Loop Until exitcount
    CountDimensions = numDimensions - 1 'subtract 1 as the last 1 was the error
End Function
Reply
#5
(09-15-2025, 11:28 PM)madscijr Wrote: No, good sir, I think you got it. Is an array 1-dimensional, 2 or 3? 

I have a case where an array is passed in and it could be any of those.

I guess the simplest way to tell (for now) is the On Error method. 

As you say, we could reserve the first element of the first dimension of all arrays to hold that info, although that would make more work having to modify all routines that return arrays, and also be harder to understand later on for someone else reading the code. 

Thanks for lending your brain to this!
You're welcome. I've loaned my brain out lots of times. How do you think zombie movies originated?

Pete Big Grin
Reply
#6
Something like this might be a little better for this type routine:

Code: (Select All)
Dim a(2, 2, 2) As Integer ' Example: a 3-dimensional array


Print "Number of dimensions: "; CountDimensions(a())
Sleep
Print UBound(a, 6) 'to show that error reports now work as expected
End

ErrorHandler:
If Err = 9 Then ' Subscript out of range error
    exitcount = _TRUE
    Resume Next ' Continue execution after the error
Else
    Print "An unexpected error occurred: "; Err
    End
End If

Function CountDimensions (arr() As Integer)
    On Error GoTo ErrorHandler
    Shared exitcount
    exitcount = _FALSE
    Do
        numDimensions = numDimensions + 1
        ' Attempt to get the upper bound of the current dimension
        ' If this dimension doesn't exist, an error will occur
        dummy = UBound(arr, numDimensions)
    Loop Until exitcount
    CountDimensions = numDimensions - 1 'subtract 1 as the last 1 was the error
    On Error GoTo 0 'turn off error handling so we get proper error reports
End Function
Reply
#7
I like that, it feels cleaner and less like a "hack" wrapped up in a nice little function like that.
Reply
#8
(09-15-2025, 11:52 PM)Pete Wrote:
(09-15-2025, 11:28 PM)madscijr Wrote: Thanks for lending your brain to this!
You're welcome. I've loaned my brain out lots of times. How do you think zombie movies originated?

Pete Big Grin
"Send more paramedics!"  Tongue
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  _NEWIMAGE can't accept variables as dimensions? bobalooie 23 915 02-18-2026, 11:16 PM
Last Post: Unseen Machine
  Maximum Number of Attachments per Thread Magdha 7 445 01-13-2026, 10:13 AM
Last Post: Magdha
  Random Number Generator pmackay 14 1,231 07-30-2025, 12:56 PM
Last Post: SMcNeill
  Illegal string-number conversion Herve 7 753 07-07-2025, 09:53 AM
Last Post: a740g
  generating a random number in the full range of that number? (Integer, Long) madscijr 2 641 05-01-2025, 09:11 PM
Last Post: madscijr

Forum Jump:


Users browsing this thread: 1 Guest(s)