#fortran #gfortran #sunstudio
#fortran #gfortran #sunstudio
Вопрос:
При компиляции с использованием GNU Fortran (версия 4.4.3) или Sun Studio F95 (версия 8.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'
Это ошибка при вызове 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
Ответ №1:
Это не создает никаких проблем с компилятором fortran от Intel с помощью -check bounds; и xlf от IBM, который, по моему опыту, чрезвычайно строг, также не жаловался на -qcheck.
Но в более широком смысле, да, нет стандарта о том, что должна или не должна делать проверка границ. Я, конечно, понимаю, почему некоторые компиляторы бы отметили присвоение массиву нулевой длины как плохое / неправильное / странное; это странный угловой случай.
Комментарии:
1. Да, это то, что я подозревал, у Sun было выдающееся поведение. Ну что ж, это просто означает, что мне нужно убедить владельца кода обернуть кучу подпрограмм в модули, а не размахивать мечом соответствия стандартам.