# Explicit-Shape Specifications

An explicit-shape array is declared with explicit values for the bounds in each dimension of the array. An explicit-shape specification takes the following form:

([dl:] du[, [dl:] du] ...)

dl | Is a specification expression indicating the lower bound of the dimension. The expression can have a positive, negative, or zero value. If necessary, the value is converted to integer type. If the lower bound is not specified, it is assumed to be 1.
du | Is a specification expression indicating the upper bound of the dimension. The expression can have a positive, negative, or zero value. If necessary, the value is converted to integer type.

The bounds can be specified as constant or nonconstant expressions, as follows:

- If the bounds are constant expressions, the subscript range of the array in a dimension is the set of integer values between and including the lower and upper bounds. If the lower bound is greater than the upper bound, the range is empty, the extent in that dimension is zero, and the array has a size of zero.

- If the bounds are nonconstant expressions, the array must be declared in a procedure. The bounds can have different values each time the procedure is executed, since they are determined when the procedure is entered.

  The bounds are not affected by any redefinition or undefinition of the variables in the specification expression that occurs while the procedure is executing.

  The following explicit-shape arrays can specify nonconstant bounds:

  - An automatic array (the array is a local variable)

  - An adjustable array (the array is a dummy argument to a subprogram)

The following are examples of explicit-shape specifications:

    INTEGER I(3:8, -2:5)         ! Rank-two array; range of dimension one is
    ...                          ! 3 to 8, range of dimension two is -2 to 5
    SUBROUTINE SUB(A, B, C)
      INTEGER :: B, C
      REAL, DIMENSION(B:C) :: A  ! Rank-one array; range is B to C

Consider the following:

     INTEGER M(10, 10, 10)
     INTEGER K(-3:6, 4:13, 0:9)

`M` and `K` are both explicit-shape arrays with a rank of 3, a size of 1000, and the same shape (10,10,10). Array `M` uses the default lower bound of 1 for each of its dimensions. So, when it is declared only the upper bound needs to be specified. Each of the dimensions of array `K` has a lower bound other than the default, and the lower bounds as well as the upper bounds are declared.

## Automatic Arrays

An automatic array is an explicit-shape array that is a local variable. Automatic arrays are only allowed in function and subroutine subprograms, and are declared in the specification part of the subprogram. At least one bound of an automatic array must be a nonconstant specification expression. The bounds are determined when the subprogram is called.

The following example shows automatic arrays:

    SUBROUTINE SUB1 (A, B)
      INTEGER A, B, LOWER
      COMMON /BOUND/ LOWER
      ...
      INTEGER AUTO_ARRAY1(B)
      ...
      INTEGER AUTO_ARRAY2(LOWER:B)
      ...
      INTEGER AUTO_ARRAY3(20, B*A/2)
    END SUBROUTINE

Consider the following:

     SUBROUTINE EXAMPLE (N, R1, R2)
       DIMENSION A (N, 5), B(10*N)
       ...
       N = IFIX(R1) + IFIX(R2)

When the subroutine is called, the arrays `A` and `B` are dimensioned on entry into the subroutine with the value of the passed variable `N`. Later changes to the value of `N` have no effect on the dimensions of array `A` or `B`.

## Adjustable Arrays

An adjustable array is an explicit-shape array that is a dummy argument to a subprogram. At least one bound of an adjustable array must be a nonconstant specification expression. The bounds are determined when the subprogram is called.

The array specification can contain integer variables that are either dummy arguments or variables in a common block.

When the subprogram is entered, each dummy argument specified in the bounds must be associated with an actual argument. If the specification includes a variable in a common block, the variable must have a defined value. The array specification is evaluated using the values of the actual arguments, as well as any constants or common block variables that appear in the specification.

The size of the adjustable array must be less than or equal to the size of the array that is its corresponding actual argument.

To avoid possible errors in subscript evaluation, make sure that the bounds expressions used to declare multidimensional adjustable arrays match the bounds as declared by the caller.

In the following example, the function calculates the sum of the elements of a rank-two array. Notice how the dummy arguments `M` and `N` control the iteration:

      FUNCTION THE_SUM(A, M, N)
        DIMENSION A(M, N)
        SUMX = 0.0
        DO J = 1, N
          DO I = 1, M
            SUMX = SUMX + A(I, J)
          END DO
        END DO
        THE_SUM = SUMX
      END FUNCTION

The following are examples of calls on `THE_SUM`:

    DIMENSION A1(10,35), A2(3,56)
    SUM1 = THE_SUM(A1,10,35)
    SUM2 = THE_SUM(A2,3,56)

The following example shows how the array bounds determined when the procedure is entered do not change during execution:

    DIMENSION ARRAY(9,5)
    L = 9
    M = 5
    CALL SUB(ARRAY,L,M)
    END

    SUBROUTINE SUB(X,I,J)
      DIMENSION X(-I/2:I/2,J)
      X(I/2,J) = 999
      J = 1
      I = 2
    END

The assignments to `I` and `J` do not affect the declaration of adjustable array `X` as `X`(-4:4,5) on entry to subroutine `SUB`.

Parent topic: Declarations for Arrays

## See Also

Specification expressions