I've been looking through this Ada 95 tutorial. I was reading that it is possible to define a type that has a range that is different than the standard range, and if the program tries to go outside this range it will throw an error. While working on my own program I noticed that if the end of the range in the definition falls on the boundary for of its underlying type then the program will not raise the CONSTRAINT_ERROR when assigning values out of that range. Instead it will happily keep going and then wrap around. I wrote a program to explicitly show this.
Does anyone know of an Ada rule that explains this behavior?
-Kirk
Here is the output from my terminal, the source code is below that.
me@acheron:~/Dropbox/programs/ada$ gnatmake constraints.adb -f
gcc-4.6 -c constraints.adb
gnatbind -x constraints.ali
gnatlink constraints.ali
me@acheron:~/Dropbox/programs/ada$ ./constraints
Type ON has size: 7
It has a min/max of: 0 127
It's base has a min/max of: -128 127
Type UNDER has size: 7
It has a min/max of: 0 126
It's base has a min/max of: -128 127
The value of No_Error is: 245
raised CONSTRAINT_ERROR : constraints.adb:58 range check failed
me@acheron:~/Dropbox/programs/ada$
Source Code:
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
Procedure Constraints is
type UNDER is range 0..126;
type ON is range 0..127;
type OVER is range 0..128;
Error : UNDER := 0;
No_Error : ON := 0;
Index : INTEGER := 0;
begin
New_Line;
Put("Type ON has size: ");
Put(INTEGER(ON'SIZE));
New_Line;
Put("It has a min/max of: ");
Put(INTEGER(ON'FIRST));
Put(INTEGER(ON'LAST));
New_Line;
Put("It's base has a min/max of: ");
Put(INTEGER(ON'BASE'FIRST));
Put(INTEGER(ON'BASE'LAST));
New_Line;
New_Line;
Put("Type UNDER has size: ");
Put(INTEGER(UNDER'SIZE));
New_Line;
Put("It has a min/max of: ");
Put(INTEGER(UNDER'FIRST));
Put(INTEGER(UNDER'LAST));
New_Line;
Put("It's base has a min/max of: ");
Put(INTEGER(UNDER'BASE'FIRST));
Put(INTEGER(UNDER'BASE'LAST));
Safe_Loop:
loop
No_Error := No_Error + 1;
Index := Index + 1;
--Put(INTEGER(No_Error));
exit Safe_Loop when Index = 245;
end loop Safe_Loop;
New_Line;
Put("The value of No_Error is: ");
Put(INTEGER(No_Error));
Index := 0;
Crash_Loop:
loop
Error := Error + 1;
Index := Index + 1;
exit Crash_Loop when Index = 245;
end loop Crash_Loop;
end Constraints;