CONTIGUOUS (Fortran 2008)
Purpose
The CONTIGUOUS attribute specifies that the array elements of an array pointer, an assumed-shape array, or an assumed-rank object are not separated by other data objects.
An array pointer with the CONTIGUOUS attribute can only be pointer associated with a contiguous target. An assumed-shape array or an assumed-rank object with the CONTIGUOUS attribute is always contiguous; however, the corresponding actual argument can be contiguous or noncontiguous. For details, see the Rules section.
Syntax
Rules
The entity that is specified with the CONTIGUOUS attribute must be an array pointer, an assumed-shape array, or an assumed-rank object.
In a pointer assignment, if the pointer has the CONTIGUOUS attribute, the target associated must be contiguous. The actual argument that corresponds to a pointer dummy argument with the CONTIGUOUS attribute must be simply contiguous.
- Create a temporary contiguous argument to associate with the dummy argument.
- Initialize the temporary contiguous argument with the value of the actual argument.
- When control returns from the procedure, copy the value of the
temporary contiguous argument back to the actual argument. Note: The value is not copied back if the actual argument is specified as INTENT(IN).
If an actual argument is a nonpointer array with the ASYNCHRONOUS or VOLATILE attribute but is not simply contiguous, and the corresponding dummy argument has either the VOLATILE or ASYNCHRONOUS attribute, that dummy argument must be an assumed-shape array without the CONTIGUOUS attribute.
If an actual argument is an array pointer with the ASYNCHRONOUS or VOLATILE attribute but without the CONTIGUOUS attribute, and the corresponding dummy argument has either the VOLATILE or ASYNCHRONOUS attribute, that dummy argument must be an array pointer or an assumed-shape array without the CONTIGUOUS attribute.
Compatible attributes
Examples
Example 1: CONTIGUOUS attribute specified for an array pointer
INTEGER, CONTIGUOUS, POINTER :: ap(:)
INTEGER, TARGET :: targ(10)
INTEGER, POINTER :: ip(:)
LOGICAL :: contig
! Invalid because ap is contiguous. A severe error is issued at compile time.
ap => targ(1:10:2)
ip => targ(1:10:2)
! contig has a value of .FALSE.
contig = IS_CONTIGUOUS(ip)
! contig has a value of .TRUE.
ALLOCATE(ip(10))
contig = IS_CONTIGUOUS(ip)
Example 2: CONTIGUOUS attribute specified for an assumed-shape array
LOGICAL :: contig
! Define a derived type named base
TYPE base(k, j, l)
INTEGER, KIND :: k, j
INTEGER, LEN :: l
INTEGER(k) :: x
INTEGER(j) :: y(l)
END TYPE
! Declare an allocatable, assumed-shape array b of base type
TYPE(base(4, 8, 0)), ALLOCATABLE :: b(:)
! Allocate two elements to b
ALLOCATE(b(2))
! contig has a value of .FALSE.
contig = IS_CONTIGUOUS(b%x)
Example 3: CONTIGUOUS attribute specified for an assumed-shape array
INTEGER, POINTER :: p(:)
INTEGER, TARGET :: t(10) = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
p => t(1:10:2)
! The actual argument p, which corresponds to the contiguous dummy argument,
! is not contiguous. The compiler makes it contiguous by creating a temporary
! contiguous argument.
CALL fun(p)
CONTAINS
SUBROUTINE fun(arg)
! Contiguous dummy argument arg
INTEGER, CONTIGUOUS :: arg(:)
PRINT *, arg(1)
END SUBROUTINE