Arrays, Dynamic Bounds & own Variables

Array bounds are evaluated when the block is entered, so they may depend on values computed in enclosing blocks (not in the same block head):

10.1 Array declarations

Bounds are arbitrary integer expressions; the lower bound may be negative or zero.

Subscripts are written in square brackets; real subscripts are rounded to integers.

Any number of dimensions is allowed.

'real' 'array' v[1:10];                  'comment' 10 elements;
'integer' 'array' m[0:3, 0:3];           'comment' 4 x 4 matrix;
'real' 'array' a, b[1:n], c[0:n, 0:n];   'comment' a and b share bounds [1:n];

10.2 Dynamic bounds

Array bounds are evaluated when the block is entered, so they may depend on values computed in enclosing blocks (not in the same block head):

This was a major advance over FORTRAN's fixed-size arrays and requires stack allocation of variable-size storage at run time.

'begin'
    'integer' n;
    ininteger(0, n);
    'begin'
        'real' 'array' data[1:n];        'comment' size chosen at run time;
        'integer' i;
        'real' sum;
        sum := 0;
        'for' i := 1 'step' 1 'until' n 'do'
        'begin'
            inreal(0, data[i]);
            sum := sum + data[i]
        'end';
        outstring(1, "mean = ");
        outreal(1, sum / n)
    'end'
'end'

10.3 Arrays as parameters

Array parameters are normally passed by name (no copy). If you specify 'value' a, the whole array is copied on entry — legal but expensive.

There are no array assignments, array operators or array-valued functions in ALGOL 60; copy element by element.

'real' 'procedure' sum(a, lo, hi);
    'value' lo, hi; 'integer' lo, hi; 'real' 'array' a;
'begin'
    'integer' i; 'real' s;
    s := 0;
    'for' i := lo 'step' 1 'until' hi 'do' s := s + a[i];
    sum := s
'end';

10.4 own variables

An own variable keeps its value between successive activations of its block — like static in C:

Caveats (part of why own was controversial):

The Revised Report does not specify an initial value; the program above assumes zero, which many implementations (including MARST, per the Modified Report's rules) provide — but portable code initializes explicitly with a flag.

With recursion, all activations share the same own variable.

own arrays with dynamic bounds are ill-defined; the Modified Report requires constant bounds for own arrays.

'begin'
    'integer' 'procedure' next id;
    'begin'
        'own' 'integer' counter;
        counter := counter + 1;
        next id := counter
    'end';
    'integer' k;
    'for' k := 1 'step' 1 'until' 3 'do' outinteger(1, next id)
'end'