Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REDIM _PRESERVE multi-dimensional array shifts data #27

Closed
Kroc opened this issue Jan 22, 2018 · 2 comments
Closed

REDIM _PRESERVE multi-dimensional array shifts data #27

Kroc opened this issue Jan 22, 2018 · 2 comments
Assignees
Labels

Comments

@Kroc
Copy link

Kroc commented Jan 22, 2018

Though the unpredictability of changing the sizes of non-last dimensions in a multi-dimension arrays is common knowledge in most forms of BASIC, the QB64 documentation does not specifically call this out. The documentation implies that it should work, and the compiler / run-time gives no warnings or error. Your data just magically gets messed up!

Test code:

PRINT "REDIM TEST"
REDIM TEST(1 TO 2, 1 TO 3) AS INTEGER
LET TEST(1, 1) = 100
LET TEST(1, 2) = 200
LET TEST(1, 3) = 300
PRINT TEST(1, 1); TEST(1, 2); TEST(1, 3)
REDIM _PRESERVE TEST(1 TO 3, 1 TO 3) AS INTEGER
PRINT TEST(1, 1); TEST(1, 2); TEST(1, 3)
END

Suggested solutions:

  • Changing the bounds of a non-last dimension in a multi-dimensional array should produce a run-time error
  • QB64 should ensure data integrity and move the data to the correct locations

I am building a two dimensional cross-check array, where the bounds are increasing as new data is read in. It would be difficult to store all the data (without knowing the final bounds until read) and dimension the array at the end.

@ghost
Copy link

ghost commented Jan 22, 2018

Verified.

QB64 indeed gets this wrong somehow, and I'm not entirely certain why INTEGER is taking up 4 bytes instead of 2 originally, or why it switches to require 6 bytes instead of the original 4, though it at least sets the correct segment when it comes to usage with VARSEG:

Before:
   100     200     300    // Value
7C31B0  7C31B4  7C31B8    // real offset (_MEM)
9FFF:0  9FFF:4  9FFF:8    // VARSEG:VARPTR

After:
   100       0       0    // Value
7C31A0  7C31A6  7C31AC    // real offset (_MEM)
9FFE:0  9FFE:6  9FFE:C    // VARSEG:VARPTR

The proper output would be something like the following:

Before:
   100     200     300    // Value
7C31B0  7C31B2  7C31B4    // real offset (_MEM)
9FFF:0  9FFF:2  9FFF:4    // VARSEG:VARPTR

After:
   100     200     300    // Value
7C31A0  7C31A2  7C31A4    // real offset (_MEM)
9FFE:0  9FFE:2  9FFE:4    // VARSEG:VARPTR

The same bug occurs even if allocated outside of the "cmem" block:

Before:
   100     200     300
000B20  000B24  000B28

After:
   100       0       0
000B20  000B26  000B2C

Expected output, assuming no reallocation:

Before:
   100     200     300
000B20  000B22  000B24

After:
   100     200     300
000B20  000B22  000B24

@FellippeHeitor
Copy link
Collaborator

Moved to https://github.com/QB64Team/qb64

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants