zxbasic icon indicating copy to clipboard operation
zxbasic copied to clipboard

Incorrect array indexing when passed as parameter

Open oskostenko opened this issue 1 year ago • 3 comments

Hi,

Having the following code:

sub PrintArray(arr() as integer)
    dim i as integer
    for i = lbound(arr, 1) to ubound(arr, 1)
        print i; ": "; arr(i)
    next i
end sub

dim arr(1 to 3) as integer => {10, 20, 30}

PrintArray arr

The expected output is:

1: 10
2: 20
3: 30

Actual output:

1: 20
2: 30
3: 0

Is it a bug or a feature?

oskostenko avatar Oct 08 '24 17:10 oskostenko

Thanks for reporting. Indeed this is a long known bug: functions are unaware of array dimensions. They will always access the array with the array-base. The solution is not easy (or at least a performant / efficient one). I was thinking on removing the feature of allowing declaring arrays with lower and upper dimensions, and use only number of elements (like in C and other languages), because is a nightmare and a feature seldom used.

Using #pragma array_base=1 or the --array-base=1 command line flag has the same effect and prevents this problem.

Will keep you updated with the fix of this. :-)

boriel avatar Oct 11 '24 22:10 boriel

Thank you very much for replying.

functions are unaware of array dimensions

What's the most annoying here, is that lbound and ubound inside the function are aware of array dimensions, and work inconsistently with how the array is actually accessed.

Using #pragma array_base=1 or the --array-base=1 command line flag has the same effect and prevents this problem.

Alas, it doesn't prevent the problem:

#pragma array_base=1

sub PrintArray(arr() as integer)
    dim i as integer
    for i = lbound(arr, 1) to ubound(arr, 1)
        print i; ": "; arr(i)
    next i
end sub

dim arr(3) as integer => {10, 20, 30}

PrintArray arr

Gives the same incorrect output:

1: 20
2: 30
3: 0

I hope this will be fixed soon. To me, 1-based arrays seem very beneficial in Basic, because I find it very awkward to always calculate length - 1 when declaring arrays and iterating over them. Zero-based arrays are absolutely fine in languages like C because of the way they are declared and iterated over, but not in Basic..

oskostenko avatar Oct 12 '24 06:10 oskostenko

Yes, but that's because, regardless of the array base functions are totally agnostic of the arrays and dimensions they receive, and operate on base 0. Giving support to these will be very expensive (in terms on memory and speed), but can be done using using the internal LBound and UBound tables. I will try to implement a solution.

In the (long) meantime, you can use lbound to subtract the index if needed. In your case:

#pragma array_base=1

sub PrintArray(arr() as integer)
    dim i as integer
    for i = 0 to ubound(arr, 1) - lbound(arr, 1)
        print i; ": "; arr(i)
    next i
end sub

dim arr(3) as integer => {10, 20, 30}

PrintArray arr

This will work regardless of how the array was declared and the array base. If you want to retrieve the original index, use Lbound(arr, 1) + i

EDIT: Array declarations will be changed in the future 2.x, and all of them will be 0-based or 1-based only. I'm seriously considering removing the DIM a(x1 TO y1, x2 TO y2...) syntax. This will allow a simpler implementation in array access within functions that will operate on the array_base selected (array base can be dynamically changed using #pragma as the example above, so a function can temporarily enforce array_base 0 and restore the previous one upon return, making it compatible to any type of array -i.e. when implementing a library).

boriel avatar Oct 13 '24 21:10 boriel

Please, consider joining the official telegram channel to discuss this with the community: https://t.me/+ydBiLEzi0_M1OWZk

boriel avatar Oct 28 '24 09:10 boriel

Please, try this beta, and let me know if it works: http://www.boriel.com/files/zxb/zxbasic-v1.18.0-beta1.tar.gz http://www.boriel.com/files/zxb/zxbasic-v1.18.0-beta1.zip http://www.boriel.com/files/zxb/zxbasic-v1.18.0-beta1-win32.zip http://www.boriel.com/files/zxb/zxbasic-v1.18.0-beta1-linux64.tar.gz http://www.boriel.com/files/zxb/zxbasic-v1.18.0-beta1-macos.tar.gz

boriel avatar Nov 03 '24 09:11 boriel

Works correctly now, thank you! 👍

oskostenko avatar Nov 03 '24 15:11 oskostenko