blakemor@software.org (Alex Blakemore) (11/13/90)
  I asked Norm Cohen to explain why the null range in his fix to my 
earlier problem (constraint error question for language lawyers).
I was surprised that declaring an array with a null range that
did not match the constraints of the index subtype of the array
did not raise constraint_error.  This was his reply.
I am posting it because it may be of interest to others.
                                        Alex Blakemore
and here's Norm ...
---------------------------
Bounds of a null range ARE allowed to be outside the corresponding
index subtype, as in String(1 .. 0).  It's hard to explain this just
by citing RM paragraph numbers; I have to quote a few sentences.
For each kind of constraint, the RM gives rules explaining when the
constraint is "compatible" with the type mark it follows.  Compatibility
is checked at run time, when a subtype indication is elaborated
(see RM 3.3.2(8)).  The rule for compatibility of an index constraint
with a type mark denoting an array type, given in 3.6.1(4), is given in
terms of a rule presented earlier, in 3.5(4), for compatibility of a
range constraint with a type mark denoting a discrete type.
RM 3.6.1(4) states,
   An index constraint is _compatible_ with the type denoted by the
   type mark if and only if the constraint defined by each discrete
   range is compatible with the corresponding index subtype.
RM 3.5(4) states,
   A range constraint is _compatible_ with a subtype if each bound of
   the range belongs to the subtype, or if the range constraint
   defines a null range; otherwise the range constraint is not
   compatible with the subtype.
For example, given the declarations
   type Short is range 0 .. 10;
   type Positive_Short is Short range 1 .. Short'Last;
   type Short_String is array (Positive_Short range <>) of Character;
   SS : Short_String (1 .. 0);
3.6.1(4) tells us that the index constraint (1 .. 0) is compatible with
the type mark Short_String if and only if the range constraint 1 .. 0
is compatible with the subtype Positive_Short.  3.5(4) says that the
range constraint 1 .. 0 is compatible with Positive_Short (even though
the upper bound of the range does not belong to the subtype) because
the range constraint defines a null range.
Unfortunately, this is not quite the same as saying that "all null
ranges are the same."  Try the following program:
- - - - - - - - - - - - - -(cut here)- - - - - - - - - - - - - - - - - -
procedure All_Null_Ranges_Are_Not_The_Same is
   type Short is range 0 .. 10;
   subtype Positive_Short is Short range 1 .. Short'Last;
   type Short_String is array (Positive_Short range <>) of Character;
   type Short_String_In_A_Record (Length: Short) is
      record
         C : Short_String (1 .. Length);
      end record;
   Null_String : Short_String (0 .. -1);
   SSR : Short_String_In_A_Record (Length => 0);
begin
   SSR := (Length => 0, C => Null_String);
   -- Raises Constraint_Error because the constraint on SSR.C is 1 .. 0 but
   --   the constraint on Null_String is 0 .. -1.  Both are legitimate null
   --   ranges, but they are not the SAME null range!
end All_Null_Ranges_Are_Not_The_Same;
----------------------------------------------------------------------
Alex Blakemore                       blakemore@software.org
Software Productivity Consortium
2214 Rock Hill Road Herndon, VA 22070 (703) 742-7125gargulak@mozart.convex.com (Tom Gargulak) (11/14/90)
One thing I failed to mention. I assume that the program will raise a storage_error exception due to the infinite recursion. I realize some compilers can optimize this into a loop. So, assuming the exception occurs, will this program eventually terminate? Why? Thanks again, Tom