Подтвердить что ты не робот

Где поставить `implicit none` в Fortran

Нужно ли помещать implicit none внутри каждой функции и подпрограммы?

Или это достаточно, чтобы поместить его в начало модуля, содержащего эти функции и подпрограммы?

Или это достаточно, чтобы поместить его в начало программы, использующей эти модули?

От наблюдения другого рабочего кода implicit none включен во все эти места. Я не уверен, что это делается избыточно, потому что удаление implicit none из подпрограмм, которые все еще скомпилированы и которые выдают тот же результат.

Кстати, я использую gfortran fortran 90.

4b9b3361

Ответ 1

Оператор implicit (включая implicit none) применяется к блоку определения области видимости. Такая вещь определяется как

Конструкция BLOCK, определение производного типа, тело интерфейса, программный блок или подпрограмма, исключая все вложенные единицы измерения в нем

Это "исключение всех вложенных единиц измерения в нем" предполагает, что может быть необходимо/желательно иметь implicit none для каждой функции и подпрограммы (в совокупности, процедуры), определенных в модуле. Однако внутри процедур, содержащихся в модуле, имеется сопоставление по умолчанию, основанное на узле определения области хоста. Таким образом, с implicit none в модуле нет необходимости иметь это в содержащихся процедурах.

Это правило единицы измерения хоста применимо в равной степени к внутренним программам. Это означает, что implicit none в основной программе охватывает все процедуры, содержащиеся в ней; и что то же самое относится к внутренним программам модульных процедур. Конструкции блоков также видят это, и оператор implicit даже не разрешен внутри одного из них.

Однако внешние функции/подпрограммы не наследуют неявное поведение от программы или модуля, а модули не наследуют его от программ/других модулей, которые use их. Это явно имеет смысл, поскольку неявное типирование должно быть известно во время компиляции и должно быть четко определено независимо от их конечного использования.

Кроме того, нельзя делать

implicit none
use somemodule

end program

Инструкция implicit должна соответствовать всем операторам use.

Это правило узла определения области видимости не относится к объектам интерфейса. Ответ IanH мотивирует это исключение, но это достаточно важно для повторного стресса. Это вызвало много путаницы.

module mod
 implicit none

  interface
    subroutine external_sub()
      ! The default implicit typing rules apply here unless there is an implicit
      ! statement, such as implicit none.  Those from the module aren't in force here.
    end subroutine
  end interface

end module

Что касается теста удаления implicit none из подпрограммы: если код действителен с implicit none, тогда он должен быть действительным и идентичным без этого оператора. Все сущности должны быть явно объявлены в первом случае, поэтому в последнем случае не будут применяться неявные правила.

Ответ 2

Нет, да (вроде) и №

Один раз на программный блок (который не то же самое, что один раз для каждой программы) и в каждом корпусе интерфейса достаточно.

Программный модуль является либо основной программой, либо модулем, либо внешней подпрограммой (функцией или подпрограммой подпрограммы, которая не появляется после оператора CONTAINS другого типа программного блока), блоком данных блока данных или подмодулем. Если не указано иначе с оператором IMPLICIT, по умолчанию в каждом программном модуле используется сопоставление по умолчанию, начиная с I-N как целого по умолчанию, а все остальное - по умолчанию.

Тот же принцип применяется к объектам интерфейса - поскольку они должны быть моментальным снимком части спецификации процедуры, определенной в другом программном модуле. Этот другой программный блок имел бы сопоставление по умолчанию, если иное не указано иначе, поэтому тело интерфейса имеет сопоставление по умолчанию, если иное не указано иначе.

Внутри программного модуля внутренние подпрограммы или подпрограммы модуля наследуют любые неявные типизации, указанные в их узле, в отсутствие "локального" оператора IMPLICIT в самой подпрограмме.

Избыточная спецификация IMPLICIT NONE безвредна. Вы часто видите, что подпрограммы, которые раньше были внешними подпрограммами, были помещены в модуль.

Ответ 3

Вот неофициальный ответ, основанный на том, что работает для меня.

Мой код Fortran состоит из двух типов файлов: те, которые содержат основную программу и те, которые содержат один модуль. В каждом виде файла IMPLICIT NONE появляется сразу после операторов "program foo" или "module foo" и после операторов USE вверху. Он не отображается в подпрограммах или функциях, потому что это будет избыточным.

Ответ 4

Если вы используете gfortran, вы можете просто добавить параметр -fimplicit-none.

Обратите внимание, что это решение, специфичное для компилятора. Другие распространенные компиляторы могут не поддерживать этот параметр. Например, Intel ifort игнорирует это как неизвестный вариант.