In comp.lang.ada Ian Bell wrote: :James Rogers> foo : My_Array_Type; :> :> for num in 0..99 loop :> foo(num) := num; :> end loop; :> :> All Ada compilers will correctly identify the error in the for loop. :> [...] : : I know nothing about ada so this is a genuine query rather than a ctiticism. : The above example is fine as long as literals are used - even a C compiler : could be devised to make this check - but what happens when the array index : is computed?
Wouldn't that become a famous compiler that finds out, at compile time, which value a certain variable is going to have? :-)
If you want a hole in your foot, you can make one, though it might not be easy:
with Interfaces; with Ada.Integer_Text_IO; use Ada;
procedure t is -- read a positive value from standard input and create an -- array of that size, which is filled (hopping excessively)
procedure rubber_buffer(limit: Positive) is
subtype Index is Positive range 1 .. limit; -- a range constraint on Positive, determined at call time
buffer: array(Index) of Interfaces.Unsigned_8; -- storage for 1 .. limit 8bit quantities
begin -- demonstration of constraint_error
off_buffer: -- k grows too large for a buffer index
for k in Index'first .. 2 * Index'last loop buffer(k) := 42; -- index check failed, at run time end loop off_buffer;
off_index_range: -- k gets too large for Index subtype's range
for k in Index'first .. Index(2 * Index'last) -- range check failed, at run time loop buffer(k) := 42; end loop off_index_range;
end rubber_buffer;
n: Positive; -- upper limit of 1-based buffer, read at run time
begin Integer_Text_IO.get(n); rubber_buffer(n); end t;
That's why language-defined array constructs such as the 'range attribute are useful. You can write
for k in buffer'range loop buffer(k) := 42; end loop;
(or in this case more simply, using language defined `others'
buffer := (others => 42);)
no matter what the buffer's index range currently is.
-- Georg