Debugging Techniques

Print variable values at key points: PRINT "i="; i; " total="; total.

32.1 Types of errors

How you find it Syntax / compile errors PRNT "Hi", missing END IF IDE status bar, compile log division by zero, subscript out of range, file not found error dialog with line number wrong formula, off-by-one loop testing, tracing, debugger

32.2 The QB64-PE IDE

The status bar shows syntax errors as you type; the IDE won't compile until they're fixed.

OPTION _EXPLICIT catches misspelled variables at compile time.

Interactive debugger: add $DEBUG to the program (or enable debug mode), then use F9 to toggle breakpoints, F7/F8 to step into/over, and the watch list to inspect variables while the program runs.

Run-time error dialogs show the line number; choose to continue or quit.

32.3 Print and log debugging

Print variable values at key points: PRINT "i="; i; " total="; total. In graphics programs, draw debug text in a corner with _PRINTSTRING, or send it to the console with _ECHO or _DEST _CONSOLE.

$CONSOLE
_ECHO "Debug: starting level 1"        ' write to the console window without disturbing graphics
DIM SHARED debugOn AS INTEGER
debugOn = -1

SUB DebugLog (msg AS STRING)
    IF NOT debugOn THEN EXIT SUB
    DIM f AS INTEGER
    f = FREEFILE
    OPEN "debug.log" FOR APPEND AS #f
    PRINT #f, TIME$; " "; msg
    CLOSE #f
END SUB

32.4 Assertions

With $ASSERTS enabled, a failed _ASSERT stops with your message; remove $ASSERTS for release builds and the checks disappear.

$ASSERTS
DIM idx AS LONG
idx = 11
_ASSERT idx >= 1 AND idx <= 10, "idx out of range in UpdatePlayer"

32.5 Classic techniques

STOP pauses execution (in QBasic you could inspect variables in the Immediate window and continue with F5).

TRON/TROFF traced line numbers in GW-BASIC.

Rubber-duck debugging: explain the code line by line to someone (or something); the bug often becomes obvious.

Divide and conquer: comment out half the code or insert checkpoints to narrow down where things go wrong.

Minimal reproduction: copy the failing part into a tiny new program.

Known input → expected output: test with values you can compute by hand; use RANDOMIZE with a fixed seed so random behavior is reproducible.

32.6 Common BASIC bugs

Variable is always 0 misspelled name (implicit new variable) — use OPTION _EXPLICIT; or a local variable shadows a global (missing DIM SHARED) "Subscript out of range" off-by-one loop bounds, wrong OPTION BASE, undeclared array defaulting to 0–10 "Parameter type mismatch" variable passed by reference has a different type than the parameter Number prints with extra space

STR$ and PRINT add a leading space for positive numbers; use _TRIM$

Values change unexpectedly after a SUB call parameter passed by reference was modified inside the SUB INTEGER exceeded 32,767 — use LONG Condition always true used NOT on a value that isn't -1/0 (NOT 1 = -2 is true) AND condition reads out of bounds

BASIC evaluates both sides — check bounds first in a separate IF or use _ANDALSO missing _DISPLAY, or CLS drawn to the visible screen 100% CPU usage loop without _LIMIT or SLEEP

Fixed-length strings don't compare equal trailing spaces — use RTRIM$ File data garbled mixing PRINT # with INPUT # for strings containing commas — use WRITE # or LINE INPUT #

Program runs at different speeds on different PCs empty-loop delays — use _LIMIT or delta time

FreeBASIC: compile with -g and debug with GDB (or an IDE front end); -exx adds array-bounds and null-pointer checks; Assert(cond) with -g. VB.NET: Visual Studio's debugger (breakpoints, conditional breakpoints, watch, immediate window, edit and continue), Debug.WriteLine, Debug.Assert, unit testing with MSTest, NUnit, or xUnit.

🧪 Part III Exercises

Draw a scene in SCREEN 12 using only LINE, CIRCLE, PAINT, and DRAW (house, tree, sun, and a DRAW-based star).

Plot y = sin(x), y = cos(x), and y = x²/10 on the same axes using WINDOW, each in a different color, with labeled axes.

Build an animated analog clock in a 32-bit screen with _DISPLAY, using TIME$ and trigonometry for the hands.

Write a sprite-sheet animator that loads a PNG sheet, plays a walk cycle, and moves the character with _KEYDOWN.

Compose a 16-bar tune with PLAY, and a sound-effect generator (laser, explosion, coin) with _SNDRAW.

Make a mouse-driven paint program with a color palette bar, brush sizes on the wheel, and save-to-BMP or a custom binary format.

Implement the game loop with delta time and a fixed-timestep physics update; show that speed is the same at _LIMIT 30 and _LIMIT 240.

Benchmark bubble, insertion, Shell, quick, and merge sort on 1,000, 10,000, and 50,000 items; print a results table.

Implement an expression evaluator for + - * / ( ) using two stacks (shunting-yard algorithm).

Create a plasma effect using _MEMIMAGE and compare its speed with a PSET version; then split your graphics helpers into a .bi/.bm library.