为什么 GNAT 拒绝具有默认判别值的数组类型?

Tam*_*inn 5 ada

此(声明)代码引发存储错误:

type Vector is array (Integer range <>) of Integer;
type Array_Starting_At_One (Max : Integer := 0) is
   record
      Mat : Vector (1 .. Max);
   end record;

X : Array_Starting_At_One;
Run Code Online (Sandbox Code Playgroud)

我不明白为什么。如果我指定默认值,X : Array_Starting_At_One (Max => 0);则错误消失,尽管 Array_Starting_At_One 类型规范仍会触发警告,即创建此类对象可能会引发 Storage_Error。

我什至不想存储一个位,所以这个错误对我没有任何意义:

raised STORAGE_ERROR : System.Memory.Alloc: object too large
Run Code Online (Sandbox Code Playgroud)

Jim*_*ers 5

当然,任何索引范围为 1..Integer'Last 的数组都可能引发 Storage_Error。编译器警告您这种可能性。尝试限制数组类型的索引范围,例如:

subtype Indices is Integer range 0..1024;
type Vector is Array (Indices range <>) of Integer;
type Array_Ending_At (Max : Indices := 0) is
   record
      Mat : Vector(1..Max);
   end record;
Run Code Online (Sandbox Code Playgroud)


egi*_*lhh 5

当使用默认判别式声明变量时,稍后可以通过赋值更改判别式。这意味着编译器(至少 GNAT 会这样做)将分配(在堆栈上)足够的空间来容纳具有最大允许值(在本例中为 Integer'Last)的任何判别式的对象。

要么增加堆栈大小(不一定推荐),要么使用更适合您的问题的不同子类型:

subtype Foo is Integer range 1..10;
type Vector is array (Foo range <>) of Integer;
Run Code Online (Sandbox Code Playgroud)