Концептуальные различия между двумя картами до очень значительных практических различий.
Линия INCLUDE работает на уровне источника - она выполняет простое («немое») включение текста. В отсутствие какой-либо специальной интерпретации процессора «имя файла» (нет требования для этого фактически быть файлом) в строке включения полный источник может быть легко скомбинирован вручную программистом и передан компилятору без разницы, что -со-всегда в семантике источника. Включенный источник не имеет реальной интерпретации в изоляции - его смысл полностью зависит от контекста, в котором появляется строка включения, которая ссылается на включенный источник.
Модули работают на гораздо более высоком уровне сущности программы, то есть на уровне, где компилятор рассматривает вещи, которые на самом деле описывает источник. Модуль может быть скомпилирован изолированно от своих подчиненных пользователей, и как только он был скомпилирован, компилятор точно знает, какие вещи модуль может предоставить программе.
Обычно то, что кто-то использует линию включает в надежда делать то, что модули были фактически разработаны сделать.
Пример проблемы:
Поскольку декларации сущностей могут быть распределены по нескольким ведомостям объекты, описываемые включенным источником не может быть то, что вы ожидаете. Рассмотрим следующий источник должны быть включены:
INTEGER :: i
В изоляции это выглядит следующим образом объявляет имя i
как целое скаляр (или, возможно, в зависимости кто знает?!). Теперь рассмотрим следующую сферу, которая включает в себя выше:
INCLUDE "source from above"
DIMENSION :: i(10,10)
i
теперь ранга два массива! Возможно, вы хотите сделать это POINTER? ПОЛЕЗНОЕ? Фиктивный аргумент? Возможно, это приводит к ошибке, или, возможно, это действительно источник! Бросьте неявное типирование в микс, чтобы действительно создать потенциальную забаву.
Объект, определенный в модуле, «полностью» определяется модулем. Атрибуты, специфичные для области использования, могут быть изменены (VOLATILE, доступность и т. Д.), Но основной объект остается неизменным. Вызовы имени вызываются явно, и их можно легко обойти с предложением переименования в заявлении USE.
У Fortran есть ограничения на упорядочение операторов (спецификации должны доставляться перед исполняемыми инструкциями и т. Д.). Включенный источник также подвергается этим ограничениям, опять же в контексте точки включения, а не точки определения источника.
Хорошо сочетается с исходной неоднозначностью между определениями функций оператора (спецификация) и инструкциями присваивания (исполняемая часть) для некоторых полностью тупых сообщений об ошибках или, что еще хуже, молчания принятия компилятором ошибочного кода.
Существуют требования, в которых появляется инструкция USE, которая ссылается на модуль, но источник для модуля модуля модуля полностью не зависит от его точки использования.
Нужно ли иметь какое-либо глобальное состояние для совместного использования связанных процедур и вы хотите использовать include? Позвольте мне представить вам общие блоки и связанную с ними базовую концепцию объединения последовательностей ...
Связь последовательностей является неудачным прорастанием ранней базовой реализации процессора Fortran, которая является склонной к ошибкам, негибкой, анахронизмом против оптимизации.
Переменные модуля делают общие блоки и связанные с ними зла совершенно ненужными.
Если вы использовали строки включения, обратите внимание, что на самом деле вы не включаете источник обычно используемой процедуры (предложение в вашем первом абзаце просто приведет к болоту синтаксических ошибок от компилятора) , То, что вы обычно делаете, это источник, описывающий интерфейс процедуры. Для любой нетривиальной процедуры источник, описывающий интерфейс, отличается от полного источника процедуры - подразумевая, что теперь вам нужно поддерживать два представления источника одной и той же вещи. Это ошибка, связанная с нагрузкой на обслуживание.
Как уже упоминалось, компиляторы автоматически получают информацию о интерфейсе модульной процедуры (знание компилятора является «явным», потому что на самом деле он видел код процедуры - отсюда и термин «явный интерфейс»). Нет необходимости программисту делать что-то еще.
Следствия вышесказанного является то, что внешние подпрограммы не должны использоваться на всех исключения случаев, когда есть очень хорошие причины, чтобы наоборот (возможно существование круговых или чрезмерно обширных зависимости) - основная отправная точка должна быть поставить все в модуле или основной программе.
Другие плакаты упоминали исходный код организации преимущества модулей - в том числе способность к группирования связанных процедур и других «вещей» в одном пакете, с контролем над доступностью внутренних деталей реализации.
Я принимаю, что существует допустимое использование строк INCLUDE в соответствии с вторым абзацем вопроса - где большие модули становятся громоздкими по размеру. F2008 обратился к этому с подмодулями, что также приносит ряд других преимуществ. После того, как они станут широко поддерживаться, следует отказаться от использования линейной работы.
Второе допустимое использование заключается в том, чтобы преодолеть недостаток поддержки со стороны языка для общих методов программирования (какие шаблоны предоставляют на C++) - то есть, где типы объектов, участвующих в операции, могут различаться, а последовательность токенов, которая описывает, что делать на этих объектах по существу то же самое. Это может быть еще какое-то десятилетие или около того, до того, как выйдет этот язык.
Итак, нет никакого недостатка в разделении подпрограмм в разных файлах, а затем использование include внутри модуля, правильно? Раньше я никогда не слышал о подмодулях. – Nordico
Я бы рассматривал это только в том случае, если у меня были очень большие исходные файлы или как часть миграции исходного кода. Если возможно, я бы сначала подумал о том, чтобы разбить модуль на несколько «дочерних» модулей, которые затем агрегируются вместе с операторами USE в родительском модуле. Однако при сложных зависимостях типа/процедуры и/или в том, как работает доступность Fortran PUBLIC/PRIVATE, использование дочерних модулей может быть не всегда возможным. Вы можете обнаружить, что сшивание источника для модуля вместе с INCLUDE приводит к путанице с некоторыми системами сборки. – IanH