Ada CONSTRAINT_ERROR does not rise when it "should"

I looked at this Ada 95 tutorial . I read that it is possible to determine a type that has a range other than the standard range, and if the program tries to go beyond this range, it will cause an error. While working on my own program, I noticed that if the end of the range in the definition falls on the border for its base type, then the program will not raise CONSTRAINT_ERROR when assigning values ​​from this range. Instead, he will happily go on and then turn around. I wrote a program to explicitly show this.

Does anyone know the Ada rules that explain this behavior?

-Kirk

Here is the output from my terminal, the source code is below this.

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 base has a min/max of: -128 127 Type UNDER has size: 7 It has a min/max of: 0 126 It 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:

 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 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 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; 
+4
source share
1 answer

According to the documentation :

Note that the -gnato option -gnato disabled by default, so overflow checking is not performed in default mode. This means that due to default restrictions, GNAT does not perform all the checks expected from a language description in the Ada Reference Guide. If you want all constraint checks to be performed as described in this manual, then you must explicitly use the -gnato switch in either the gnatmake or gcc command.

However, the documentation also states that:

Basically, the rule is that in the default mode ( -gnato not used), the generated code ensures that all integer variables remain within the declared ranges or in the base range if there is no declared range. This prevents any serious problems, such as out-of-range indexes for array operations. & Item; What is not checked in the default mode is overflow, which leads to an incorrect but incorrect value.

which seems wrong in the case you described, as No_Error really completely goes beyond its range. Thus, this seems to go beyond the “not [& hellip;] expected from the language description” to the “compiler error” area; but at least you can fix this by adding the -gnato flag.

+3
source

Source: https://habr.com/ru/post/1438791/


All Articles