Моя точка зрения состояла в основном в том, чтобы избежать доступа к переменным модуля, которые определены в том же модуле и которые должны использоваться другими процедурами модуля, и как избежать доступа к ним.
====================================================================================================================================================================================================================

1вопрос связан с вызовом и вызываемыми подпрограммами в Fortran 90. Я совершенно запутался в правилах ассоциации host / use / arguments; У меня проблемы с пониманием логики определения объема, вытекающей из этих правил. Возможно, самый простой способ разоблачить мою проблему - объяснить, чего я хотел бы достичь и почему.

Я хотел бы удовлетворить два требования дизайна:

(i) Вызывающая подпрограмма только позволяет вызываемой подпрограмме получить доступ к своим объектам, которые передаются в качестве аргументов, никаким другим. (ii) Вызываемая подпрограмма не позволяет вызывающей подпрограмме получить доступ к любому из объектов, которые она определяет локально.

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

2Конечно, Fortran 90 предлагает возможность использовать модули и вариант «только». Например, можно сделать следующее:

Конечно, my\_sub\_a будет максимально разрешен доступ к тем объектам my\_mod\_b, для которых my\_sub\_b является областью видимости. Но сможет ли он получить доступ к объектам my\_sub\_b, отличным от списка аргументов, который он передает? В частности, сможет ли my\_sub\_a получить доступ к объектам, локальным для my\_sub\_b? И наоборот, разрешает ли ассоциация использования my\_sub\_b обращаться к объектам my\_sub\_a, отличным от тех, которые передаются в качестве фактических аргументов?

3Является ли следующая конструкция «буферного модуля» достаточной для того, чтобы соответствовать требованиям # 1?

4Есть ли более простая конструкция для достижения целей # 1?

5Следуя предложениям, предложенным Россом и Владимиром Ф.,

одна возможность может быть:

(я), чтобы иметь взаимно-однозначное соответствие между модулями и подпрограммами,

(ii) объявлять локальные переменные в модуле вместо подпрограммы; затем можно пометить локальные переменные как «частные».

Просто чтобы быть уверенным, что я правильно понял, вот тривиальная программа, которая иллюстрирует (i ') и (ii'):

В этом примере единственная сущность sub\_a, к которой может обращаться sub\_b, - это v0 (связь аргументов); u0 останется скрытым для sub\_b. И наоборот, тег 'private' гарантирует, что переменная w0 остается вне области действия sub\_a, даже если sub\_a ИСПОЛЬЗУЕТ модуль sub\_b\_module. Это правильно?

@Ross: Спасибо, что указали на предыдущий пост, где связь унаследована. Однако у меня сложилось впечатление, что это касается только половины моей проблемы; конструкция, обсуждаемая в этом посте, иллюстрирует, как можно запретить программному модулю вызывающей стороны получить доступ к объектам вызываемого программного модуля, которые должны оставаться скрытыми (опции «использовать только» и / или «частные»), но я не могу с уверенностью утверждать, что объекты программной единицы вызывающей стороны, которые не связаны с аргументами, останутся недоступными для вызываемой программной единицы.

раммы (и ее внутренних процедур) - поэтому они называются «локальными переменными». Вы можете достичь своих целей дизайна в части 1 вашего вопроса без каких-либо особых усилий.

Переменные, которые не являются локальными переменными (например, переменные модуля, переменные в общем блоке), могут быть доступны или совместно использовать информацию в разных областях - это, как правило, причина того, что эти другие виды переменных существуют в языке. Если вы не хотите такого рода обмена информацией, не используйте эти другие виды переменных!

Предложения в части 5 отредактированного вопроса идут не в ту сторону ...



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

Fortran 2015 обеспечивает больший контроль над выделением хоста с помощью`IMPORT`, Я не уверен, затрагивает ли это также процедуры модуля, но это могло бы. Но вы просите древний Fortran 90, так что, вероятно, вас это не интересует (так или иначе, компиляторы его еще не реализовали), но я оставлю его здесь на будущее:

Если один оператор импорта в области видимости является`import,only` оператор, все они должны быть, и только перечисленные объекты становятся доступными для хост-ассоциации. Если`import,none` оператор появляется в области видимости, никакие сущности не доступны для хост-ассоциации, и он должен быть единственным`import` Выписка в обзорном отделении. ... (От: Reid (2017)Новые возможности Fortran 2015)

Да, ваш пример более или менее правильный, хотя существует много возможных вариантов. Вы всегда можете добавить`only` предложение документа, почему вы используете модуль и какие символы импортируются.

**Важный:** Я предлагаю вам не ставить`implicit none` внутри содержащиеся процедуры, но один раз в модуле. Вы определенно хотите, чтобы переменные модуля покрывались`implicit none`! И используйте некоторые отступы, чтобы структура действительно была видна при просмотре блока кода.

Если вы используете только один исходный файл, вам определенно нужно разместить модули и программу в другом порядке:

Если вы супер заботитесь о доступе к данным, вы можете сделать модули`mod_sub_a`, `mod_sub_b`, `mod_sub_c` каждая с одной общедоступной подпрограммой. Тогда модуль`subroutines` который использует те, и пусть весь другой код использует только модуль`subroutines` чтобы получить доступ к этим.

Чтобы быть ясным - из ответа IanH, который я вижу, возможно, здесь было какое-то недопонимание - я, конечно, НЕ рекомендую однозначное соответствие модулей и подпрограмм. Я считаю это довольно экстремальной вещью, чтобы убедиться в вашей главной мысли:

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

Итак, я показал вам, как убедиться, что ваша подпрограмма не имеет доступа к чему-либо извне - поместив ее в модуль, к которому больше нет доступа. Я также показал вам будущее с`import` это можно использовать для отключения доступа к другим объектам, определенным в модуле хоста.

Я просто проигнорировал твой второй пункт

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

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