[comp.lang.ada] null ranges and index constraints

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-7125

gargulak@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