Range checks in Ada are basically assignment guards with some cute arithmetic attached. Ada still does most of the useful checking at runtime, so you're really just introducing more "index out of bounds". Consumer this example:
procedure Sum_Demo is
subtype Index is Integer range 0 .. 10;
subtype Small is Integer range 0 .. 10;
Arr : array(Index) of Integer := (others => 0);
X : Small := 0;
I : Integer := Integer'Value(Integer'Image(X)); -- runtime evaluation
begin
for J in 1 .. 11 loop
I := I + 1;
end loop;
Arr(I) := 42; -- possible out-of-bounds access if I = 11
end Sum_Demo;
This compile, and the compiler will tell you: "warning: Constraint_Error will be raised at run time".
It's a stupid example for sure. Here's a more complex one:
procedure Sum_Demo is
subtype Index is Integer range 0 .. 10;
subtype Small is Integer range 0 .. 10;
Arr : array(Index) of Integer := (others => 0);
X : Small := 0;
I : Integer := Integer'Value(Integer'Image(X)); -- runtime evaluation
begin
for J in 1 .. 11 loop
I := I + 1;
end loop;
Arr(I) := 42; -- Let's crash it
end Sum_Demo;
This again compiles, but if you run it: raised CONSTRAINT_ERROR : sum_demo.adb:13 index check failed
It's a cute feature, but it's useless for anything complex.
The comment to which I replied is about two concepts: Defining subtypes and an optimization made possible by them.
I get a lot of value out of compile time enforcement of subtypes (e.g., defining a function as requiring a parameter be Index instead of Integer) finding errors in my thinking. It is more than "cute" to me.
As for the possible optimization of the array bounds check and it happening at runtime instead of compiletime, isn't that a failure of GNAT and not Ada? Can't a sufficiently smart compiler detect the problem in your example?
Regardless, I am not convinced that getting around the compiletime type safety by casting with Integer'Value(Integer'Image(X)) proves anything. I will still prefer having subtypes over not having them.
procedure Sum_Demo is subtype Index is Integer range 0 .. 10; subtype Small is Integer range 0 .. 10;
begin for J in 1 .. 11 loop I := I + 1; end loop; end Sum_Demo;This compile, and the compiler will tell you: "warning: Constraint_Error will be raised at run time".
It's a stupid example for sure. Here's a more complex one:
This again compiles, but if you run it: raised CONSTRAINT_ERROR : sum_demo.adb:13 index check failedIt's a cute feature, but it's useless for anything complex.