Массивы нулевого размера и проверка границ массива

#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 было выдающееся поведение. Ну что ж, это просто означает, что мне нужно убедить владельца кода обернуть кучу подпрограмм в модули, а не размахивать мечом соответствия стандартам.