Reputation: 3248
This (declaration) code raises a storage error:
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;
I can't figure out why. If I specify the default, as in X : Array_Starting_At_One (Max => 0);
the error disappears, although the Array_Starting_At_One type specification still triggers a warning that creation of such objects may raise Storage_Error.
I am not even trying to store a single bit, so this error doesn't make any sense to me:
raised STORAGE_ERROR : System.Memory.Alloc: object too large
Upvotes: 5
Views: 290
Reputation: 3358
As you notice, this is a compiler issue. The Janus/Ada compiler would accept your code without complaint or run-time exception.
Your variable X
is an unconstrained object; the discriminant (and so the size of the object) can be changed by full-record assignment. The ARM is silent about how such things should be implemented. GNAT has chosen to allocate enough space for the largest possible value; since X
is allocated on the stack, there will not be enough space for it with GNAT's default stack size (if you allocate it on the heap, you might not have a problem). Janus instead allocates only enough space for the current value, which may result in X.Mat
being implicitly allocated on the heap.
The Janus way is more developer-friendly and acceptable for most applications, where the developer doesn't care where things are allocated, but there are situations where implicit heap allocation cannot be accepted, so the GNAT way is more general.
Upvotes: 3
Reputation: 6430
When a variable is declared using the default discriminant, then the discriminant can later be changed via an assignment. This means that the compiler (at least GNAT does this) will allocate (on the stack) enough room to hold an object with any discriminant up to the maximum allowed value (Integer'Last in this case).
Either increase your stack size (not neccessarily recommended), or use a different subtype more suited to your problem:
subtype Foo is Integer range 1..10;
type Vector is array (Foo range <>) of Integer;
Upvotes: 5
Reputation: 5021
Certainly any array with an index range of 1..Integer'Last could raise Storage_Error. The compiler is warning you of this possibility. Try restricting the index range for your array type such as:
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;
Upvotes: 5