Array Types

An array is a constant sized list of elements. An array type is expressed with the ``array of` keyword followed by the name of any valid Type; an optional size can be provided in square brackets. The lower bound of an array does not have to be 0.

var x: array of Integer;         // an array of undetermined (as of yet) size
var y: array [0..9] of Integer;  // an array fixed to 10 elements
var z: array [5..10] of Integer; // an array fixed to 6 elements, with a lower bound of 5.

Arrays can be made multidimensional, by providing more than one set of bounds.

var x: array[0..9, 0..9] of Integer; // 10x10 = 100 integers
var y: array[0.., 0..] of Integer;   // an undetermined (but rectangular) number of integers
var z: array of array of Integer;    // an undetermined (loose) number of integers

Static Arrays

It is worth noting that arrays with fixed specified bounds are automatically allocated by the compiler, on the stack as value types, and can be immediately used. These are referred to as Static Arrays.

var x: array[0..9] of Integer; // these 10 integers now exist as space on the stack
x[3] := 42;                     // so we can just set the one at index 3 to "42"

The same holds true for multi-dimensional arrays with fixed bounds. These are allocated as a monolithic block of memory, so essentially array [0..99] of Integer and array [0..9, 0..9] of Integer have the same memory representation. Merely the semantics of how the 100 individual items get accessed differs.

var y: array[0..9, 0..9] of Integer; // these 100 integers too exist as space on the stack
x[3,8] := 42;                         // so we can just set the one at index 3 to "42"

Platform Considerations

  • Static arrays are reference types, on .NET and Java, and stored on the heap, while they are value types on Cocoa and Island and stored on the local stack.

Dynamic Arrays

Arrays without bounds (or with open bounds) are un-initialized reference types, and set to nil by default (because, after all, their actual size is not known from the declaration). These are referred to as Dynamic Arrays.

To use, fill these arrays with values, a copy needs to be instantiated using the new operator:

var x: array of Integers; // unknown number of Integers, for now
x := new Integer[20];     // so we need to allocate 20 of them in memory (indexed 0..19)
x[3] := 42;               // *now* we can set the one at index 3 to "42"
var x: array [0.., 0..] of Integers; // unknown number of Integers, for now
x := new Integer[20,20];  // so we need to allocate 400 of them in memory (indexed 0..19/0..19)
x[3,8] := 42;               // *now* we can set the one at index 3 to "42"

For loose multi-dimensional dynamic arrays, each level would need to be instantiated manually (since each level can, in theory, contain a different-sized sub-array):

var x: array [0.., 0..] of Integers; // unknown number of Integers, for now

x := new array of Integer[50];       // we allocate 50 arrays for dimension one (indexed 0..49)
for i: Integer := 0 to 49 do
  x[i] = new Integer[20];            // and for each, we allocate 20 integers — for a total of 50*20 = 1000

x[3,8] := 15;                        // now we can set values

Dynamic arrays are always reference types.

Inline Arrays

Inline arrays are concept specific to arrays on the .NET platform. The inline Type Modifier ensures that memory for the arrays is allocated with the stack space or the memory space of the containing Class or Record.

type
  MyRecord = public record
  public
    Chars: inline array[0..255] of Byte;
  end;

The above record's size would be 256 bytes, unlike a record with a regular array, which would be stored outside of the record. Inline arrays are specially useful when working with P/Invoke to call native code.

.NET Only

The Inline Array syntax is available on the .NET platform only.

Inline arrays are considered "unsafe". In order to use them, the "Allow Unsafe Code" Compiler Option must be enabled, and any Methods that deal with them must be marked with the unsafe Member Modifier.

See Also