Question on array aggregates

Assume the following declaration:
type x_array1_type is array(Integer range <>) of real;

And the array:
x : constant x_array1 := x_array1_t’[1.0, 2.0, 3.0];

Then the indexes range from Integer’First to Integer’First + 2 (I assume).

The compiler gives the warning:
warning: value not in range of type “Standard.Integer” [enabled by default]

How can I make the range to become, for example 1…3 ? (or -103,…-101)?

The way to do it is:
x : constant x_array1(-103…-101) := x_array1_t’[1.0, 2.0, 3.0];

?

reinert

I would write it like this:

   type x_array1_type is array(Integer range <>) of Float;
   x : constant x_array1_type (-103 .. -101) := (1.0, 2.0, 3.0);

Hope it helps.

I don’t think you can be showing us your actual code.

This compiles OK (apologies for reformat, recase):

pragma Ada_2022;
package Reinert is
   type X_Array1_Type is array(Integer range <>) of Float;
   X : constant X_Array1_Type := X_Array1_Type'[1.0, 2.0, 3.0];
end Reinert;

Yes, I was a bit incomplete. I would like to use the statement:

return [1.0, 2.0, 3.0];

and at the same time have some control over the index but still keep flexibility.
I could use

return a : X_Array1_Type(1..3) := X_Array1_Type'[1.0, 2.0, 3.0];

Maybe that is the simplest way. Possible to define a (rather safe) 
default lower bound which is not too far negative?

Also, the compiler warn about this statement:
  y : x_array1_type := [];
warning: Pred of "Integer'First" [enabled by default]
warning: Constraint_Error will be raised at run time [enabled by default]

So could it be possible to enable by default for 
example 1 instead of  "Integer'First" ?

Would a named array aggregate help? You can specify the indexes for those:
See examples here: Array Aggregates

pragma Ada_2022;

with Ada.Text_IO; use Ada.Text_IO;

procedure jdoodle is
    type Array_Type is array (Integer range <>) of Float;
    
    function Test return Array_Type is
    begin
        return [-1 => 1.0, 0 => 2.0, 1 => 3.0];
    end Test;
    
    Thing : constant Array_Type := Test;
    
begin
    for Index in Thing'Range loop
        Put_Line(Index'Image & " => " & Thing(Index)'Image);
    end loop;
end jdoodle;

Output:

-1 =>  1.00000E+00
 0 =>  2.00000E+00
 1 =>  3.00000E+00

gcc -c jdoodle.adb
gnatbind -x jdoodle.ali
gnatlink jdoodle.ali -o jdoodle

Hopefully approaching :slight_smile:
I slightly modified your example storing numbers in a container:

with Ada.Text_IO; use Ada.Text_IO;
with ada.containers.ordered_sets;

procedure jdoodle is
    type Array_Type is array (Integer range <>) of Float;

    package container_set_p is new
       ada.containers.ordered_sets(element_type => float);
    use container_set_p;
    container_set : constant container_set_p.set := [1.0,2.0,3.0];

    function Test return Array_Type is
    begin
        return [for e of container_set => e];
    end Test;

    Thing : constant Array_Type := Test;

begin
    for Index in Thing'Range loop
        Put_Line(Index'Image & " => " & Thing(Index)'Image);
    end loop;
end jdoodle;

I compiled using:

   package Compiler is
      for Default_Switches ("ada") use ("-gnatwa","-gnata","-gnatX0","-gnatwl");
   end Compiler;

It gives:

-2147483648 =>  1.00000E+00
-2147483647 =>  2.00000E+00
-2147483646 =>  3.00000E+00

How can you in a simple way make the lower index
to become -1 (without loosing too much generality)?

I’ve got into the habit of declaring arrays like this using (Natural range <>) (or even Positive), thus avoiding a world of pain (as you’ve found).

If you sometimes would like to use negative indexes, what would you do?

Maybe something like this (see “subtype i_Type” below):

with Ada.Text_IO; use Ada.Text_IO;
with ada.containers.ordered_sets;

procedure jdoodle is
    subtype i_Type is Integer range -1..Integer'Last;
    type Array_Type is array (i_Type range <>) of Float;

    package container_set_p is new
       ada.containers.ordered_sets(element_type => float);
    use container_set_p;
    container_set : constant container_set_p.set := [1.0,2.0,3.0];

    function Test return Array_Type is
    begin
        return [for e of container_set => e];
    end Test;

    Thing : constant Array_Type := Test;

begin
    for Index in Thing'Range loop
        Put_Line(Index'Image & " => " & Thing(Index)'Image);
    end loop;
end jdoodle;

Giving:

-1 =>  1.00000E+00
 0 =>  2.00000E+00
 1 =>  3.00000E+00

Are you ok with changing:

container_set : constant container_set_p.set := [1.0,2.0,3.0];

to

container_set : constant container_set_p.set := 
   [-1 => 1.0, 
     0 => 2.0,
     1 => 3.0];

If not, you can try subtyping the result:

pragma Ada_2022;

with Ada.Text_IO; use Ada.Text_IO;
with ada.containers.ordered_sets;

procedure jdoodle is
    
    type Array_Type is array (Integer range <>) of Float;

    package container_set_p is new
       ada.containers.ordered_sets(element_type => float);
    use container_set_p;
    container_set : constant container_set_p.set := [1.0,2.0,3.0];

    function Test return Array_Type is
        subtype Formatter is Array_Type(-1 .. 1);
    begin
        return Result : Formatter := [for e of container_set => e];
    end Test;

    Thing : constant Array_Type := Test;

begin
    for Index in Thing'Range loop
        Put_Line(Index'Image & " => " & Thing(Index)'Image);
    end loop;
end jdoodle;

Output:

-1 =>  1.00000E+00
 0 =>  2.00000E+00
 1 =>  3.00000E+00

gcc -c jdoodle.adb
gnatbind -x jdoodle.ali
gnatlink jdoodle.ali -o jdoodle

I don’t know how legal this actually is since I am as practiced with the for loop initialization for aggregates, but GNAT seems to accept it.

I just hard coded the indexes for formatter but you could do something more mathy to calculate them probably.

Wouldn’t that create an array of a Integer'Last + 2 length? (i.e. Integer'Last plus the minus one and the zero)

Oh, it’s worse than that. I misread the question, answered according to a correct answer to the wrong question,then botched that, too. Easy way to fix…

You really don’t want to do that, because Array_Type values must have Integer'Last+2 elements. (0, -1, and 1..Integer'Last.)

Yep, you were probably :keyboard:ing as I was busy :wastebasket:ing (i.e., deleting). One day I’ll learn not to add to my answers while glancing back, but that day has not arrived.