Search code examples
arraysadaada2012

Understanding bounds of concatenated arrays in Ada 2012


I am reading Programming in Ada 2012 by John Barnes. In section 8.6 he discusses array concatenation and the rules for array bounds, in particular:

The lower bound of the result depends on whether the underlying array type is constrained or not. If it is unconstrained...then the lower bound is that of the left operand...[otherwise] the lower bound is that of the array index subtype.

Then in the exercises for 8.6, question 7 is as follows (I've added the answers given on the website PDF inside the [] ):

  1. Given

    type TC is array (1..10) of Integer;
    type TU is array (Natural range <>) of Integer;
    AC: TC;
    AU: TU(1..10);

What are the bounds of:

(a) AC(6..10) & AC(1..5)           [1..10]        
(b) AC(6) & AC(7..10) & AC(1..5)   [1..10]   
(c) AU(6..10)& AU(1..5)            [6..15]  
(d) AU(6) & AU(7..10) & AU(1..5)   [0..9]     

The answers to a and b made sense to me since the AC array is based on a constrained type we just use the bounds of the index. I would think the answers to c and should both be 6..15 since the underlying type is unconstrained the leftmost operand AU(6) or AU(6..10) will determine the starting bounds. Then I tried coding it up as shown below to better understand and all four show the bounds as 1..10. Is my code wrong, are the answers wrong or is the description in the text wrong? (BTW, I also coded with new array variables and made the assignments to those but the results are the same).

type TC is array (1..10) of Integer;
type TU is array (Natural range <>) of Integer;
AC: TC;
AU: TU(1..10);

begin
  AC := AC(6..10) & AC(1..5); 
  Tio.Put("7a) Constrained type starting with 6..10  ");
  Iio.Put(AC'First); Iio.Put(AC'Last); Tio.New_Line;

  Tio.Put ("7b) Constrained type starting with 6      ");
  AC := AC(6) & AC(7..10) & AC(1..5); -- 7.b
  Iio.Put(AC'First); Iio.Put(AC'Last); Tio.New_Line;

  Tio.Put ("7c) Unconstrained type starting with 6..10");
  AU := AU(6..10) & AU(1..5);
  Iio.Put(AU'First); Iio.Put(AU'Last); Tio.New_Line;
  Tio.Put_Line("Answer keys says 6..15");

  Tio.Put ("7d) Unconstrained type starting with 6    ");
  AU := AU(6) & AU(7..10)& AU(1..5);
  Iio.Put(AU'First); Iio.Put(AU'Last); Tio.New_Line;
  Tio.Put_Line("Answer key says 0..9 - Why not 6..15???");

(Tio and Iio are just renames of the std Ada io packages for text and integer)

When run, this code produces the following console output:

E:\Google Drive\SW_DEV\Ada\Sample\obj\hello
7a) Constrained type starting with 6..10            1         10
7b) Constrained type starting with 6                1         10
7c) Unconstrained type starting with 6..10          1         10
Answer keys says 6..15
7d) Unconstrained type starting with 6              1         10
Answer key says 0..9 - Why not 6..15???

Solution

  • Your AU is defined to start with lower bound of 1 (an anonymous array subtype with range 1..10). That will never change.

    For the unconstrained results (c and d) you should assign to a new variable, like this:

    declare
       AU_c : TU := AU(6..10) & AU(1..5);
       AU_d : TU := AU(6) & AU(7..10)& AU(1..5);
    begin
       -- your Put/Put_Lines here
    end;