with Ada.Text_IO;
with ada.containers.indefinite_vectors;
procedure test1 is
use ada.containers;
use Ada.Text_IO;
package arg1_p is new indefinite_Vectors(Positive, String);
n : constant Integer := 3;
arg1 : constant arg1_p.Vector := [for i in 1..n => "aaa"];
-- Clumsy alternative:
-- arg1 : constant arg1_p.Vector := (if n > 0 then [for i in 1..n => "aaa"] else []);
begin
put_line("arg1: " & arg1'Image);
end test1;
I would like that arg1 = “empty vector” when n=0, but if I try, then I get error message. I expected that the loop “i in 1..0” is an “empty loop”. Am I missing something?
arg1 : constant arg1_p.Vector := [for i in 2..n + 1 => "aaa"];
One should probably request a change. Normal practice of generic unit design is that if the unit is instantiated with a subtype then the implementation uses its base rather than the type itself. E.g. Positive → Positive’Base.
gcc version 15.2.1 20250808 (Red Hat 15.2.1-1) (GCC)
gnatmake test1.adb
gcc -c test1.adb
test1.adb:9:50: warning: value not in range of type "Ada.Containers.Indefinite_Vectors.Index_Type" from instance at line 7 [enabled by default]
test1.adb:9:50: warning: Constraint_Error will be raised at run time [enabled by default]
gnatbind -x test1.ali
gnatlink test1.ali
./test1
raised CONSTRAINT_ERROR : test1.adb:9 range check failed
I cannot test it with GNAT 14, because it is broken under Debian. But it works with Debian gcc version 13.3.0 (Debian 13.3.0-16)
.
I use the latest under alire/debian: gnat_native=15.1.2
I get this error message when compiling:
test1.adb:8:50: warning: value not in range of type “Ada.Containers.Indefinite_Vectors.Index_Type” from instance at line 6 [enabled by default]
test1.adb:8:50: warning: Constraint_Error will be raised at run time [enabled by default]
And when I try to run:
raised CONSTRAINT_ERROR : test1.adb:8 range check failed
Load address: 0x558f5803c000
[./bin/test1]
0x558f58045eec _ada_test1 at ???
0x558f5805446b main at ???
[/lib/x86_64-linux-gnu/libc.so.6]
0x7fd1c1df0ca6
0x7fd1c1df0d63
[./bin/test1]
0x558f5804266f _start at ???
0xfffffffffffffffe
I don’t have a modern compiler, but try changing the aggregate initialization expression to:
... := [for I in Integer range 1 .. n => "aaa"];
I’m surprised you have to do that, you’d think that the range would automatically use the base type of the index subtype. You always need values outside the range of the subtype in order to declare an empty range.
The subtype arg1_p.Extended_Index could also be used: that subtype is specifically declared such that it includes the values from the base type immediately outside the range of the index subtype.
Let me know whether that works. One of these days I’ll upgrade my compiler.
A range is compatible with a scalar subtype if and only if it is either a null range or each bound of the range belongs to the range of the subtype.
So a null range is compatible with all scalar subtypes, even if it has values that are not in the subtype. 1 .. 0 is a null range and so compatible with Positive.
That would be my assumption: you should always be able to specify an empty range. If the range is empty then it shouldn’t matter what the index values are.
What compiler are you using? File a ticket and see what they say.
As a work-around you can use To_Vector to initialize the vector:
with Ada.Containers.Indefinite_Vectors; use Ada.Containers;
with Ada.Text_IO; use Ada.Text_IO;
procedure test1 is
package String_Vectors is new Indefinite_Vectors (Positive, String);
use String_Vectors;
procedure Print (V : Vector) is
Index : Positive := 1;
begin
Put ("[");
if V.Is_Empty then
Put_Line ("]");
return;
end if;
loop
Put (V (Index));
Index := Index + 1;
exit when Index > V.Last_Index;
Put (",");
end loop;
Put_Line ("]");
end;
V : constant Vector := To_Vector ("aaa", Length => 3);
begin
Print (V);
end;
To_Vector has the same semantics as what you were doing, will work even when Length is 0, and only requires an Ada 2005 compiler.
with Ada.Text_IO;
with ada.containers.indefinite_vectors;
procedure Positive_Index is
use ada.containers;
use Ada.Text_IO;
package arg1_p is new indefinite_Vectors(Positive, String);
n : constant Integer := 0;
arg1 : constant arg1_p.Vector := [for i in 1..n => "aaa"];
type Array_Type is array (Positive range <>) of Integer;
Null_Array : constant Array_Type := (1..0 => 0);
Null_Array2 : constant Array_Type := [for i in 1..0 => 0];
Null_String : constant String := (1 .. 0 => ' ');
Null_String2 : constant String := (for i in 1..0 => ' ');
begin
Ada.Text_IO.Put_Line("Length of Null_String is " &
Integer'Image (Null_String'Length));
Ada.Text_IO.Put_Line("Length of arg1 is " &
arg1.Length'Image);
end Positive_Index;
With GNAT 15:
raised CONSTRAINT_ERROR : positive_index.adb:10 range check failed
The best would be to open a bug on gcc’s bugzilla: it’s the correct location to report bug found in GCC. I agree, it really looks like a compiler bug, so definitely worth opening a bug report