Ada dynamic array allocation index range

489 views Asked by At

How would I change this code to force the indices to begin with the first index 'First evaluating to 1 and last index 'Last evaluating to 'Length ?

  Menu_Text_Ptr := new Packed_Message_Array_Type'("A...",
                                                  "B...",
                                                  "C...",
                                                  "D...");

I have several dynamic arrays like this and their lengths vary. I would rather not put an explicit length of last index value because that makes code maintenance a bit more complicated. I would rather just add or subtract content from the allocation statement and let the compiler figure it out.

As it stands now, the first index 'First evaluates to -2147483648 (Which is probably something like 0x80000000).

Is it possible to do what I am asking?

This is Ada83 on GNAT.

2

There are 2 answers

0
Keith Thompson On BEST ANSWER

If your first index is -2147483648 (-231), then you've probably defined your array type Packed_Message_Array_Type as something like:

type Packed_Message_Array_Type is array(Integer range <>) of Some_Type;

If you change the index type from Integer to Positive (which is a subtype of Integer with a lower bound of 1), then the default lower bound will be 1.

In general, if you define an array variable specifying its initial value, but not specifying the lower bound, the lower bound will default to the lower bound of the index type.

(I've deleted part of this answer; I thought you could define an index for just the first element, but positional associations cannot follow named associations.)

0
ajb On

Assuming (as Keith did) that you have a type like this:

type Packed_Message_Array_Type is array(Integer range <>) of Some_Type;

If you don't want to dictate that every array have only positive indexes, but you want this array to start at 1, you could say

declare
    subtype Array_Subtype is Packed_Message_Array_Type(1..4);
begin
    Menu_Text_Ptr := new Array_Subtype'("A...",
                                        "B...",
                                        "C...",
                                        "D...");
end;

Or, if you don't want to hard-code the upper bound:

declare
    Source_Array : constant Packed_Message_Array_Type := 
          ("A...", "B...", "C...", "D...");
    subtype Array_Subtype is Packed_Message_Array_Type(1..Source_Array'Length);
begin
    Menu_Text_Ptr := new Array_Subtype'(Source_Array);
end;

I haven't tested either of these, and in particular I'm not sure the second one will work. (Also, the second one is more likely to use additional time to create an array on the stack and copy it to allocated storage, depending on how good the compiler's optimization is.)