Bounds checking
An index outside an array's bounds reads or writes memory that belongs to
something else. By default nothing stops it. Compiled with -exx, the program
checks every index and stops at the first bad one:
'' -exx makes the program check every index against the array's bounds.
#cmdline "-exx"
dim as int32 scores( 1 to 3 ) = { 70, 85, 92 }
dim as int32 i = 4 '' one past the end
scores( i ) = 100 '' stops here with runtime error 6
print "not reached"
Output
Aborting due to runtime error 6 (out of bounds array access) at line 7 of bounds.tiko::(),
'SCORES' accessed with invalid index = 4, must be between 1 and 3
#cmdline "-exx" puts the flag in the source, so the file builds the same way
wherever it is compiled. The program stops at the bad write with runtime error
6, prints which array was touched, with which index, and what the bounds are,
and exits with code 6. print "not reached" never runs. The message goes to
standard error.
The check works for dynamic arrays too. It reads the bounds the array has at
that moment, so after redim preserve a( 1 to 2 ), a( 3 ) is caught.
-exx costs a comparison on every access. Use it while writing and testing a
program. Where an index comes from outside the program, such as input or a
calculation you are not sure of, check it yourself as well, because that check
is there in every build:
'' Checking an index yourself works in every build, with or without -exx.
function ScoreAt( scores( ) as const int32, byval i as int32 ) as int32
if i < lbound( scores ) orelse i > ubound( scores ) then return -1
return scores( i )
end function
dim as int32 scores( 1 to 3 ) = { 70, 85, 92 }
for i as int32 = 0 to 4
print "ScoreAt("; i; " ) ="; ScoreAt( scores( ), i )
next
Output
ScoreAt( 0 ) =-1
ScoreAt( 1 ) = 70
ScoreAt( 2 ) = 85
ScoreAt( 3 ) = 92
ScoreAt( 4 ) =-1
Comparing against lbound and ubound works on any array. ScoreAt returns
-1 for an index outside them; Error Handling shows ways
to report a failure that cannot be confused with a real value.
Activities
- Change
ito 0 in the first example and read the new message. - Remove
#cmdline "-exx"and compile the program again. Do not rely on what it prints.