user3521388
user3521388

Reputation: 73

Array of array of records

I need to create a constant array of a constant array of records where I can reference each element of the outer array by a number.

I've tried:

A : constant array (0 .. 3) of B := (B1, B2, B3, B4) 

where B is an array of records and B1,B2,B3,B4 are constant arrays of type B.

But when I do this I get the error: "Unconstrained element type in array declaration"

type C is record
   a : Integer := 0;
   b : Integer := 0;
   c : Integer := 0;
   d : Integer := 0;
end record;

type B is array (Natural range <>) of C;

B1 : constant B := (0, 0, 0, 0);
B2 : constant B := (2, 0, 2, 0);
B3 : constant B := (0, 1, 0, 1);
B4 : constant B := (2, 1, 2, 1);

A : constant array (0 .. 3) of B := (B1, B2, B3, B4);

I was hoping to use A to be able to reference B1,B2,B3,B4 numerically like so:

A (1) returns B1

A (2) returns B2

and so on...

(I apologize if the terms I use are wrong. I'm kinda new to Ada and have been learning by trial and error...)

Upvotes: 1

Views: 874

Answers (2)

Zerte
Zerte

Reputation: 1516

What is obvious to you is not obvious to the compiler, that is all your B's have four elements.

For accessing element A(3)(2) it (or the Ada language) wants to be able to make very simple arithmetic (2 + 3 * 4) * (size of an integer). An array of B (which is unconstrained) would make this computation too complicated. The produced machine code would need to add the sizes of A(0), A(1), A(2) just to get to A(3)(0). Of course you can imagine the time it would take for much larger array lengths, just for accessing element A(1234)(5678) for instance.

This is why the designers of Ada wisely required to have always arrays of constrained types. For your problem, you can solve it by defining subtype BL4 is B (0 .. 3); and use BL4 instead of B for B1, B2, B3, B4 and A.

Upvotes: 2

egilhh
egilhh

Reputation: 6430

Your problem is that B is an unconstrained array:

type B is array (Natural range <>) of C;

This is fine for B1 : constant B := (0, 0, 0, 0);, as the constant definition creates a new anonymous type, with the range taken from the Right-Hand-Side.

It is, however, not fine for A. The compiler needs to know the size of the array elements, but cannot when the element (B in this case) is unconstrained. In addition, the constraints ('First, 'Last, etc) must be the same for all of the elements.

You can change your definition of B to be constrained:

type B is array (Natural range 1..4) of C;

This will force all your B1, B2, etc to always have four elements, which is what you already have in your example.

Also, if you want A(1) to return B1, you should change the range of A to start at 1:

A : constant array (1 .. 4) of B := (B1, B2, B3, B4);

Upvotes: 2

Related Questions