Array Shape Check: New in Intel® Fortran Compiler 19.0 BETA
The array shape checking feature implemented in Intel® Fortran Compiler 19.0 BETA checks for array shape conformance where it is required by the Fortran standard. When enabled, the compiler checks contexts at compile-time and will generate code that checks at run-time that the shapes of arrays conform in various contexts where conformance is required. Try this compiler option to help debug a program with arrays!
To enable array shape checking, compile with -check shape
(Linux* and macOS*) or /check:shape
(Windows*). Using this code as an example,
program t3 implicit none real(8) :: a(20)=1,b(20)=2 integer :: n=10,m=20 a(1:10)=3 b(1:m)=b(1:m)+a(1:n) print *,b end program t3
the array shape mismatch is detected at runtime. This example output is on Linux and is similar for Windows.
ifort -check shape t3.f90 a.out forrtl: severe (408): fort: (33): Shape mismatch: The extent of dimension 1 of array B is 20 and the corresponding extent of array A is 10 Image PC Routine Line Source a.out 0000000000405400 Unknown Unknown Unknown a.out 0000000000402CA9 Unknown Unknown Unknown a.out 0000000000402C1E Unknown Unknown Unknown libc-2.17.so 00007F3285A74AF5 __libc_start_main Unknown Unknown a.out 0000000000402B29 Unknown Unknown a.out 0000000000402C1E Unknown Unknown Unknown libc-2.17.so 00007F93C172BAF5 __libc_start_main Unknown Unknown a.out 0000000000402B29 Unknown Unknown Unknown
The severe error can be changed to a warning by also compiling with -warn shape
(Linux and macOS) or /warn:shape
(Windows) and the program prints the warning and traceback and, in this case, runs to completion.
ifort -check shape -warn shape t3.f90 a.out forrtl: warning (406): fort: (33): Shape mismatch: The extent of dimension 1 of array B is 20 and the corresponding extent of array A is 10 Image PC Routine Line Source a.out 0000000000405420 Unknown Unknown Unknown a.out 0000000000402D1B Unknown Unknown Unknown a.out 0000000000402C1E Unknown Unknown Unknown libc-2.17.so 00007F51932C3AF5 __libc_start_main Unknown Unknown a.out 0000000000402B29 Unknown Unknown Unknown 5.00000000000000 5.00000000000000 5.00000000000000 5.00000000000000 5.00000000000000 5.00000000000000 5.00000000000000 5.00000000000000 5.00000000000000 5.00000000000000 3.00000000000000 3.00000000000000 3.00000000000000 3.00000000000000 3.00000000000000 3.00000000000000 3.00000000000000 3.00000000000000 3.00000000000000 3.00000000000000
Add -traceback
to get more information about the runtime failure. In the traceback in the example below, notice that the shape mismatch is on line 6.
ifort -check shape -traceback t3.f90 a.out forrtl: severe (408): fort: (33): Shape mismatch: The extent of dimension 1 of array B is 20 and the corresponding extent of array A is 10 Image PC Routine Line Source a.out 00000000004055C0 Unknown Unknown Unknown a.out 0000000000402E58 MAIN__ 6 t3.f90 a.out 0000000000402C1E Unknown Unknown Unknown libc-2.17.so 00007F13720E8AF5 __libc_start_main Unknown Unknown a.out 0000000000402B29 Unknown Unknown Unknown
With the Fortran 2003 standard for an array assignment, if the LHS (left hand side) is an allocatable array, by default the compiler does the following:
- If the LHS is not allocated, allocate it to the size of the RHS (right hand side).
- If the LHS is allocated, but is not the same size as the RHS, then deallocate the LHS and reallocate to the size of the RHS.
- Do the actual array assignment.
As a result, for assignments with an allocatable array on the LHS, there can be no LHS/RHS shape violation. However, if you specify -assume norealloc_lhs
(Linux and macOS) or /assume:norealloc_lhs
(Windows) or -nostandard-realloc-lhs
(Linux and macOS) or /nostandard-realloc-lhs
(Windows), then the Fortran 90/95 behavior for allocatable arrays is used, and the allocatable array on the LHS must have the same size as the RHS.
For example, given the following code:
PROGRAM TR IMPLICIT NONE INTEGER, ALLOCATABLE :: A(:),B(:) ALLOCATE(A(20)) ALLOCATE(B(10)) A(:) = 10 B = A WRITE(*,*) B(1) END TR
There is no shape violation, by default, since B will be automatically re-sized to the size of A. If -assume norealloc_lhs
is specified, however, a violation does occur, and will be reported, if array shape checking is enabled.
When the array shape check compiler option is enabled, these contexts are checked:
- right-hand and left-hand side of intrinsic and elemental defined assignments,
- the operands of intrinsic and elemental defined binary operations,
- two or more array arguments to ELEMENTAL procedures,
- the ARRAY= and MASK= arguments to intrinsic procedures as required,
- and the arguments to the intrinsic module procedures IEEE_SET_FLAG and IEEE_SET_HALTING_MODE.
Array shape checking is also enabled by including -check
(Linux and macOS) or /check
(Windows) in the compile command.
Add this compiler option to your debugging toolkit!
† An array’s shape is determined by its rank and number of extents. The rank is the number of dimensions of the array and the number of elements in a dimension is called the extent of the array.