2015-01-05 42 views
0

我想使用聚合初始化一个简单的Ada数组,并且我希望编译器确定数组边界。但是,当尝试使用下面的Test_2时,我不能简单地使用整数下标。有没有办法允许编译器确定数组边界数组,然后使用简单的“Test_2(0)”符号访问它们?Ada数组聚合初始化

我正在使用gnat。

谢谢。

with Interfaces;     use Interfaces; 

procedure Test_Init is 
    type U16_a is array(Integer range <>) of Unsigned_16; 

    -- array aggregate initialization 
    Test_1 : U16_a(0..1) := (16#1234#, 16#5678#); -- ok, but... 
    Test_2 : U16_a  := (16#8765#, 16#4321#); -- let compiler create bounds 

    Test_3 : Unsigned_16; 
begin 

    -- Test_1 obviously works 
    Test_3 := Test_1(0); 

    -- warning: value not in range of subtype of "Standard.Integer" defined at line 8 
    -- This produces a constraint. 
    -- What is the subtype that is defined at line 8? It is not Integer (0..1) 
    Test_3 := Test_2(0); 

    -- this works though 
    Test_3 := Test_2(Test_2'First); 

    -- and this works 
    Test_3 := Test_2(Test_2'Last); 

    -- and this works 
    Test_3 := Test_2(Test_2'First + 1); 

end Test_Init; 

回答

6

如果不指定边界,则数组的下限是索引类型的下限。 (您可能习惯于像C,其中数组总是有下界0语言。这不是在阿达的情况。)

在这种情况下,下限为Integer'First,这可能是-2147483648

如果你想在数组边界在0开始,你可以使用子Natural

type U16_a is array(Natural range <>) of Unsigned_16; 

或者你可以使用子Positive设置数组的下界1

您还可以指定每个元素的索引:

Test_2 : U16_a  := (0 => 16#8765#, 1 => 16#4321#); 

但可能的扩展性;如果存在大量元素,则必须为每个元素指定索引,因为位置关联不能跟随命名关联。

代替使用位置或命名骨料初始化可以使用阵列级联来指定所述第一索引的:

Test_3 : U16_a := (0 => 0) & (1, 2, 3, 4, 5, 6, 7); 

参考手册中指出:

如果阵列类型的最终祖先是由一个 unconstrained_array_definition定义,那么结果的下界是 左边的操作数。

选择具有所需下限的索引子类型更为简洁。

+0

或指定聚集中的边界,如下所示:'Test_2:U16_a:=(0 => 16#8765#,1 => 16#4321#);' – egilhh

+0

@egilhh:是的,但那不规模也是如此。如果您有大量元素,则必须为每个元素指定索引,因为位置关联不能跟随命名关联。 –

+0

当然,但你可能会从文件中读取数组元素 – egilhh