getting the number of dimensions in an array on the fly? - madscijr - 09-15-2025
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.
RE: getting the number of dimensions in an array on the fly? - Pete - 09-15-2025
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
RE: getting the number of dimensions in an array on the fly? - madscijr - 09-15-2025
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!
RE: getting the number of dimensions in an array on the fly? - SMcNeill - 09-15-2025
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
RE: getting the number of dimensions in an array on the fly? - Pete - 09-15-2025
(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
RE: getting the number of dimensions in an array on the fly? - SMcNeill - 09-15-2025
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
RE: getting the number of dimensions in an array on the fly? - madscijr - 09-16-2025
I like that, it feels cleaner and less like a "hack" wrapped up in a nice little function like that.
RE: getting the number of dimensions in an array on the fly? - madscijr - 09-16-2025
(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  "Send more paramedics!"
|