прохождение массивов предполагаемой формы в двух уровнях подпрограмм (Fortran 90) - PullRequest
4 голосов
/ 23 февраля 2011

У меня были проблемы с вызовом последовательных подпрограмм с массивами предполагаемой формы в Fortran 90. Более конкретно, я вызываю два уровня подпрограмм, передавая массив предполагаемой формы в качестве параметра, но в конце концов массив теряется.Чтобы продемонстрировать это, можно следовать приведенному ниже коду.

  program main

  INTERFACE
     subroutine sub1(x)
       real, dimension(:):: x
       real C
     end subroutine sub1

     subroutine sub2(x)
       real, dimension(:):: x
       real C
     end subroutine sub2
  END INTERFACE

  real, dimension(:), allocatable:: x

  allocate(x(1:10)) ! First executable command in main
  x(1) = 5.
  call sub1(x)
  write(*,*) 'result = ',x(1)
  deallocate(x)
  end program main

  subroutine sub1(x) ! The first subroutine
  real, dimension(:):: x
  real C
  call sub2(x)
  end subroutine sub1

  subroutine sub2(x) ! The second subroutine
  real, dimension(:):: x
  real C
  C2=x(1)
  end subroutine sub2

Очень коротко, main выделяет x, затем вызывает sub1 (x).Тогда sub1 вызывает sub2 (x).Это означает, что выделенный массив передается подпрограмме, которая передает его другой подпрограмме.Я ожидал бы иметь в sub2 тот же массив, который я создал в main, но нет.Используя gdb как инструмент для его изучения, я получаю следующее:

1) В main, непосредственно перед вызовом sub1, массив x точно определен:

(gdb) px
$ 1= (5, 0, 0, 0, 0, 0, 0, 0, 0, 0)

2) Внутри sub1, непосредственно перед вызовом sub2, x также хорошо определен:

(gdb) px
$ 2 = (5, 0, 0, 0, 0, 0, 0, 0, 0, 0)

3) Внутри sub2, однако, x имеет неожиданное значение и дажеего размер абсолютно неверен:

(gdb) px
$ 3 = ()
(gdb) whatis x
type = REAL (4) (0: -1)

Итак, x был успешно передан из основного в sub1, но не из sub1 в sub2.Я использую Intel Fortran Gfortran с теми же результатами.

Я боролся с этим в течение длительного времени.Любая помощь будет высоко ценится.
Г.Оливейра.

1 Ответ

10 голосов
/ 24 февраля 2011

Использование фиктивных аргументов предполагаемой формы требует явного интерфейса.В вашей основной программе вы предоставили явные интерфейсы для двух подпрограмм, но они не распространяются на сами подпрограммы.Подпрограммы скомпилированы как отдельные модули, даже если вы поместили весь свой код в один исходный файл.
Это означает, что sub1 не имеет явного интерфейса, доступного для sub2, и, таким образом, использует неявный интерфейс, где аргументПредполагается, что x - настоящий скаляр.

Всего этого можно избежать, просто поместив две подпрограммы в модуль и use этот модуль в вашей основной программе, автоматически сделав доступными явные интерфейсы.Таким образом, вам не нужно предоставлять интерфейсы самостоятельно, что подвержено ошибкам.

В качестве примечания я советую использовать неявное none во ВСЕМ вашем коде.

...