title: Ada CONSTRAINT_ERROR not being raised when it "should"
body: <p>I've been looking through this <a href="http://www.infres.enst.fr/~pautet/Ada95/e_c03_p4.ada" rel="nofollow">Ada 95 tutorial</a>. 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.</p>
  
  <p>Does anyone know of an Ada rule that explains this behavior?</p>
  
  <p>-Kirk</p>
  
  <p>Here is the output from my terminal, the source code is below that.</p>
  
  <pre><code>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$
  </code></pre>
  
  <p>Source Code:</p>
  
  <pre><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;
  </code></pre>