CONTIGUOUS (Fortran 2008)

Purpose

The CONTIGUOUS attribute specifies that the array elements of an array pointer, an assumed-shape arrayTS 29113 begins, or an assumed-rank objectTS 29113 ends 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 TS 29113 beginsor an assumed-rank objectTS 29113 ends with the CONTIGUOUS attribute is always contiguous; however, the corresponding actual argument can be contiguous or noncontiguous. For details, see the Rules section.

Syntax

Read syntax diagramSkip visual syntax diagram
>>-CONTIGUOUS--+----+--contiguous_array_list-------------------><
               '-::-'                          

contiguous_array
an array that is contiguous

Rules

The entity that is specified with the CONTIGUOUS attribute must be an array pointer, an assumed-shape arrayTS begins, or an assumed-rank objectTS 29113 ends.

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.

If the actual argument that corresponds to an assumed-shape array dummy argument TS beginsor an assumed-rank dummy argumentTS 29113 ends with the CONTIGUOUS attribute is not contiguous, and the call is made from Fortran or the callee is a Fortran procedure, the compiler makes it contiguous by performing the following actions:
  1. Create a temporary contiguous argument to associate with the dummy argument.
  2. Initialize the temporary contiguous argument with the value of the actual argument.
  3. 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

The following table lists the attributes that are compatible with the CONTIGUOUS attribute.
Table 1. Attributes compatible with the CONTIGUOUS attribute
AUTOMATIC  1  OPTIONAL SAVE
ASYNCHRONOUS POINTER STATIC  1 
DIMENSION PRIVATE TARGET
EXTERNAL PROTECTED  2  VOLATILE
INTENT PUBLIC  
Notes:
  •  1  IBM extension
  •  2  Fortran 2003

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


Voice your opinion on getting help information Ask IBM compiler experts a technical question in the IBM XL compilers forum Reach out to us