The Fortran 2008 Standard introduced the CONTIGUOUS attribute for assumed shape arrays and pointers. The CONTIGUOUS attribute may help the compiler optimize more effectively, see /content/www/us/en/develop/articles/vectorization-and-array-contiguity.html. However, specifying the CONTIGUOUS attribute for an assumed shape array or pointer that may not be contiguous can lead to incorrect behavior at run-time. First introduced in the Intel® Fortran Compiler version 18, the compiler option, -check contiguous, allows an application to check at run-time whether the targets of contiguous pointer assignments are indeed contiguous.
Consider the following example:
module mymod ! source file inc.F90
contains
subroutine inc(b)
real, dimension(:), pointer :: b
#ifdef CONTIG
real, dimension(:), contiguous, pointer :: c
#else
real, dimension(:), pointer :: c
#endif
c => b
c = 1.
end subroutine inc
end module mymod
program drive_inc ! source file drive_inc.F90
use mymod
implicit none
integer, parameter :: n=25, stride=5
real, target, dimension(n) :: a=0.
real, pointer, dimension(:) :: b
b => a(:n:stride)
call inc(b)
print '(5F5.0)', a
end program drive_inc
Without the contiguity attribute, results are correct.
$ ifort inc.F90 drive_inc.F90; ./a.out
1. 0. 0. 0. 0.
1. 0. 0. 0. 0.
1. 0. 0. 0. 0.
1. 0. 0. 0. 0.
1. 0. 0. 0. 0.
Here, pointer c is declared as contiguous, but the actual target is not, leading to incorrect results.
$ ifort -DCONTIG inc.F90 drive_inc.F90; ./a.out
1. 1. 1. 1. 1.
0. 0. 0. 0. 0.
0. 0. 0. 0. 0.
0. 0. 0. 0. 0.
0. 0. 0. 0. 0.
With the new option -check contiguous (Linux* or macOS*) or /check:contiguous (Windows*), the compiler adds run-time tests for the assignment of a contiguous pointer to a non-contiguous target. The option -traceback (/traceback) identifies the function and source file line number at which the incorrect assignment took place. It is not necessary to compile with the debugging option -g (Linux or macOS) or /Zi (Windows) in order to get this traceback.
$ ifort -DCONTIG -check contiguous -traceback inc.F90 drive_inc.F90; ./a.out
forrtl: severe (408): fort: (32): A pointer with the CONTIGUOUS attributes is being made to a non-contiguous target.
Image PC Routine Line Source
a.out 0000000000405220 Unknown Unknown Unknown
a.out 0000000000402AEF mymod_mp_inc_ 11 inc.F90
a.out 0000000000402C23 MAIN__ 9 drive_inc.F90
a.out 0000000000402A9E Unknown Unknown Unknown
libc-2.17.so 00007F1A0A6B0B35 __libc_start_main Unknown Unknown
a.out 00000000004029A9 Unknown Unknown Unknown