A bug in QB? Or is this a feature?

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

Post Reply
User avatar
RETROQB45
Newbie
Posts: 4
Joined: Wed Jun 03, 2020 2:57 pm

A bug in QB? Or is this a feature?

Post by RETROQB45 » Thu Jun 04, 2020 6:34 am

Here's an interesting bug I've found messing with my old QuickBASIC programs.
I suspect that anyone has spotted it before, but Google doesn't seem to know anything about this :)

Please read carefully the following code and guess what it will print:

Code: Select all

DIM SHARED a(2)
a(1) = 10
PRINT "before the call:"; a(1)
f a(1)
PRINT "after the call:"; a(1)

SUB f (v)
  PRINT "in the sub before modifying:"; a(1)
  v = 2
  PRINT "in the sub after modifying:"; a(1)
END SUB
Then run it in any ORIGINAL DOS QuickBASIC (QBasic/QB4.5/PDS/VBDOS) and be shocked with its "correct" answer (10 10 10 2 :shock:)

The key point here is passing an array element by reference.
Btw this code works as expected in QB64.

And now I wonder how can it be that I've never suffered from this (didn't even know of) in my childhood? :lol:

Erik
Coder
Posts: 46
Joined: Wed Jun 20, 2007 12:31 pm
Location: LI, NY
Contact:

Re: A bug in QB? Or is this a feature?

Post by Erik » Sun Jun 21, 2020 4:49 pm

Interesting! So it basically treats the "v" parameter as a local variable in the SUB and doesn't actually update the value of the array element passed until the code is returning from the SUB.

Passing in the whole array works as expected. The source array is updated when the parameter array gets updated.

Ex:

Code: Select all

DECLARE SUB SetVals (ArrayIn() AS INTEGER)

DIM SHARED test(1) AS INTEGER

test(0) = 500
test(1) = 900

CLS
PRINT "Before sub call"
PRINT "test(0) "; test(0)
PRINT "test(1) "; test(1)
PRINT "--------------------------------------"
CALL SetVals(test())

PRINT "After sub call"
PRINT "test(0) "; test(0)
PRINT "test(1) "; test(1)
PRINT "--------------------------------------"

SUB SetVals (ArrayIn() AS INTEGER)

PRINT "Start sub call"
PRINT "test(0) "; test(0)
PRINT "test(1) "; test(1)
PRINT "ArrayIn(0) "; ArrayIn(0)
PRINT "ArrayIn(1) "; ArrayIn(1)
PRINT "--------------------------------------"

ArrayIn(0) = 400
ArrayIn(1) = 200

PRINT "End sub call"
PRINT "test(0) "; test(0)
PRINT "test(1) "; test(1)
PRINT "ArrayIn(0) "; ArrayIn(0)
PRINT "ArrayIn(1) "; ArrayIn(1)
PRINT "--------------------------------------"

END SUB
Output:

Code: Select all

Before sub call
test(0)  500 
test(1)  900 
--------------------------------------
Start sub call
test(0)  500 
test(1)  900 
ArrayIn(0)  500 
ArrayIn(1)  900 
--------------------------------------
End sub call
test(0)  400 
test(1)  200 
ArrayIn(0)  400 
ArrayIn(1)  200 
--------------------------------------
After sub call
test(0)  400 
test(1)  200 
--------------------------------------
Nice find. I'm sure that's caused headaches to others in the past.

nikomaru
Newbie
Posts: 5
Joined: Wed Nov 28, 2018 7:35 pm

Re: A bug in QB? Or is this a feature?

Post by nikomaru » Thu Aug 06, 2020 9:52 pm

Ha! I had this issue as well, creating a Frogger clone, and fixed it with passing BY instead of referencing. Just trying to save memory by not using a stupid amount of globals, sheesh!

Post Reply