17.2.4 Fixed lower bounds for array types and subtypes

Unconstrained array types and subtypes can be specified with a lower bound that is fixed to a certain value, by writing an index range that uses the syntax <lower-bound-expression> .. <>. This guarantees that all objects of the type or subtype will have the specified lower bound.

For example, a matrix type with fixed lower bounds of zero for each dimension can be declared by the following:

type Matrix is
  array (Natural range 0 .. <>, Natural range 0 .. <>) of Integer;

Objects of type Matrix declared with an index constraint must have index ranges starting at zero:

M1 : Matrix (0 .. 9, 0 .. 19);
M2 : Matrix (2 .. 11, 3 .. 22);  -- Warning about bounds; will raise CE

Similarly, a subtype of String can be declared that specifies the lower bound of objects of that subtype to be 1:

subtype String_1 is String (1 .. <>);

If a string slice is passed to a formal of subtype String_1 in a call to a subprogram S, the slice’s bounds will “slide” so that the lower bound is 1.

Within S, the lower bound of the formal is known to be 1, so, unlike a normal unconstrained String formal, there is no need to worry about accounting for other possible lower-bound values. Sliding of bounds also occurs in other contexts, such as for object declarations with an unconstrained subtype with fixed lower bound, as well as in subtype conversions.

Use of this feature increases safety by simplifying code, and can also improve the efficiency of indexing operations, since the compiler statically knows the lower bound of unconstrained array formals when the formal’s subtype has index ranges with static fixed lower bounds.

Link to the original RFC: ‘https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-fixed-lower-bound.rst