При компиляции с GNU Fortran (v4.4.3) или Sun Studio F95 (v8.3) и без проверки границ массива, следующая программа выполняется без ошибок. Однако, когда проверка границ массива включена ( gfortran -fbounds-check
и f95 -C
, соответственно), скомпилированный исполняемый файл GNU запускается снова без ошибок, тогда как скомпилированный исполняемый файл Sun Studio дает запуск -время ошибки,
****** FORTRAN RUN-TIME SYSTEM ******
Subscript out of range. Location: line 44 column 20 of 'nosize.f90'
Subscript number 2 has value 1 in array 't$27'
Это ' s ошибка в вызове sub2 ()
, который использует автоматический фиктивный аргумент массива для x
. Вызовы sub1 ()
нормально работают как с компилятором, так и с любыми флагами.
Насколько мне известно, эта программа является «законной» в том смысле, что на массив нулевого размера можно ссылаться как на массив ненулевого размера, и нет явной индексации размерности нулевой длины x
. Но есть ли какая-то нарезка массива нулевого размера или тонкость автоматического массива, которую мне здесь не хватает? И следует ли ожидать, что проверка границ массива будет вести себя одинаково для разных компиляторов, или мне следует рассматривать это как расширение, зависящее от производителя?
MODULE subs
IMPLICIT NONE
CONTAINS
SUBROUTINE sub1(x)
IMPLICIT NONE
REAL :: x(:,:)
PRINT*,'------------------------------------'
PRINT*,SHAPE(x)
PRINT*,SIZE(x)
END SUBROUTINE sub1
SUBROUTINE sub2(n1,n3,x)
IMPLICIT NONE
INTEGER,INTENT(in) :: n1, n3
REAL :: x(n1,n3)
PRINT*,'------------------------------------'
PRINT*,SHAPE(x)
PRINT*,SIZE(x)
END SUBROUTINE sub2
END MODULE subs
PROGRAM nosize
USE subs
IMPLICIT NONE
INTEGER :: n1 = 2, n2 = 2, n3 = 0
REAL,ALLOCATABLE :: x(:,:,:)
ALLOCATE(x(n1,n2,n3))
x(:,:,:) = -99.9
PRINT*,'ALLOCATED? ',ALLOCATED(x)
PRINT*,'SHAPE =',SHAPE(x)
PRINT*,'SIZE =',SIZE(x)
PRINT*,'X =',x
CALL sub1(x(:,1,:))
CALL sub2(n1,n3,x(:,1,:))
END PROGRAM nosize