8.3. ВИДИМОСТЬ

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

Для каждого идентификатора и в каждой точке текста программы правила видимости определяют набор описаний (с этим идентификатором), т. е. варианты трактовки идентификатора. Говорят, что описание видимо в данной точке текста, когда, согласно правилам видимости, оно определяет возможные трактовки его вхождения. Возникают два случая:

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

• Правила видимости определяют более чем одну трактовку. В таком случае вхождение идентификатора является правильным в данной точке, если и только если точно одно видимое описание выбирается правилами совмещения в соответствии с данным контекстом (см. разд. 6.6 для правил совмещения и разд. 8.7 для контекста, используемого при разрешении совмещения).

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

Видимость может быть прямой или видимостью по имени. Описание видимо по имени в точках программы для:

а) описания, находящегося в видимом разделе описания пакета — на месте постфикса после точки в расширенном имени, префикс которого обозначает пакет;

б) описания входа конкретного задачного типа — на месте постфикса после точки в именованной компоненте, префикс которой соответствует задачному типу;

в) описания компоненты конкретного описания именуемого типа — на месте постфикса после точки в именованной компоненте, префикс которой соответствует этому типу, а также на месте простого имени компоненты (перед составным ограничителем =>) в именованном сопоставлении компонент агрегата этого типа;

г) спецификации дискриминанта конкретного описания типа — в местах, предназначенных для описания компоненты и простого имени дискриминанта (перед составным ограничителем =>) в именованном сопоставлении дискриминанта в ограничении дискриминанта для этого типа;

д) спецификации параметра данной спецификации подпрограммы или описания входа — на месте формального параметра (перед составным ограничителем =>) в именованном сопоставлении параметра соответствующей подпрограммы или вызова входа;

е) описания параметра настройки данного настраиваемого модуля — на месте формального параметра настройки (перед составным ограничителем =>) в именованном сопоставлении соответствующей конкретизации настройки.

Наконец, в зоне описания, связанной с конструкцией, не являющейся описанием именуемого типа, любое описание видимо по имени на месте постфикса после точки в расширенном имени, префикс которого обозначает эту конструкцию.

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

Описание скрыто во внутренней зоне описания, если она содержит омоним этого описания; внешнее описание является тогда скрытым в непосредственной области действия этого внутреннего омонима. Каждое из двух описаний является омонимом другого, если оба описания имеют один и тот же идентификатор и не более чем для одного из них допустимо совмещение. Если совмещение допустимо для обоих описаний, то каждое из двух является омонимом другого в случае, если они имеют одинаковый идентификатор, символ операции или символьный литерал, а также одинаковый профиль типа параметров и результата (см. 6.6).

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

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

Там, где скрытие осуществляется таким образом, неявное описание скрыто во всей области действия другого описания (независимо от того, какое описание стоит первым); неявное описание не видимо ни по имени, ни непосредственно.

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

Пример:

procedure P is   А, В : BOOLEAN;   procedure Q is      С : BOOLEAN;      В : BOOLEAN;      -— внутренний омоним В   begin      ...      B := А;           -- означает.а.в := Р.А;      С := Р.В;         -— означает Q.C := Р.В;   end;begin   А := B;              -—означает Р.А := Р.В;end;

Примечание о видимости библиотечных модулей. Видимость библиотечных модулей определена спецификаторами совместности (см. 10.1.1) и тем фактом, что библиотечные модули неявно описаны в пакете STANDARD (см. 8.6).

Примечание об омонимах. Один и тот же идентификатор может находиться в различных описаниях и, таким образом, соответствовать различным понятиям, даже если области действия описаний перекрываются. Перекрытие областей действия описаний с одним и тем же идентификатором может получиться из-за совмещения подпрограмм и литералов перечисления. Такое перекрытие может произойти для понятий, описанных в видимых разделах пакета, а также входов, компонент записей и параметров, где имеется перекрытие областей действия охватывающих описаний пакета, описаний задачи, описаний именуемого типа, описаний подпрограмм, описаний переименований и описаний настройки. Наконец, перекрытие областей действия может быть результатом вложенности.

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

K : INTEGER := K * K;         -- неправильно T : T;                        -- неправильно procedure Р(х : P);           -- неправильно procedure Q(X : REAL := Q);   -- неправильно даже если существует функция с именем Q procedure R(R : REAL);        -- правильное, хотя создает путаницу.

Ссылки: агрегат 4.3, аргумент 2.8, базовая операция 3.3.3, библиотечный модуль 10.1, видимый раздел 7.2, вызов входа 9.5, вызов подпрограммы 6.4, задачный модуль 9, задачный тип 9.1, зарезервированное слово 2.9, знак операции 6.1, зона описания 8.1, идентификатор 2.3, именованная компонента 4.1.3, именуемый тип 3.7, конкретизация настройки 12.3, лексема 2.2, литерал 2.5, настраиваемый модуль 12, настраиваемый пакет 12.1, находится непосредственно в 8.1, непосредственная область действия 8.2, неявное описание 3.1, область действия 8.2, объект 3.2, ограничение дискриминанта 3.7.2, оператор принятия 9.5, операция 4.5, описание 3.1, описание входа 9.5, описание компоненты 3.7, описание параметра настройки 12.1, описание подпрограммы 6.1, описание типа 3.3.1, пакет 7, параметр 6.2, подпрограмма 6, постфикс

4.1.3, прагма 2.8, программный модуль 6, простое имя 4.1, распространяется 8.1, расширенное имя 4.1.3, семейство входов 9.5, совмещение 6.6, 8.7, соответствует типу 4.1, сопоставление компонент 4.3, сопоставление параметров 6.4, сопоставление параметров настройки 12.3, составной ограничитель 2.2, спецификатор использования 8.4, спецификация дискриминанта 3.7.1, спецификация литерала перечисления 3.5.1, спецификация параметра 6.1, спецификация подпрограммы 6.1, тип 3.3, указывать 3.8, формальный параметр 6.1, формальный параметр настройки 12.1.

-8.4. СПЕЦИФИКАТОРЫ ИСПОЛЬЗОВАНИЯ

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

спецификатор-использования ::= use имя-пакета {, имя-пакета};

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

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

• Потенциально видимое описание не становится прямо видимым, если рассматриваемое место программы находится непосредственно в области действия описания омонима.

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

Предвыполнение спецификатора использования не имеет другого эффекта. /

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

Следовательно, приведенные ниже строчки текста дают один и тот же эффект (в предположении существования единственного пакета Р).

use Р;

use Р; use Р, Р;

Пример противоречия имен в двух пакетах:

procedure R is   package TRAFFIC is      type COLOR is (RED, AMBER, GREEN);      ...   end TRAFFIC;   package WATER_COLORS is      type COLOR is (WHITE, RED, YELLOW, GREEN, BLUE, BROWN, BLACK);      ...   end WATER_COLORS;   use TRAFFIC;        -- COLOR, RED, AMBER, и GREEN непосредственно видимы    use WATER_COLORS;   -- Два омонима GREEN непосредственно видимы,                            -- butCOLOR не является более непосредственно видимым   subtype LIGHT is TRAPPIC.COLOR;    -- подтип использован для разрешения    subtype SHADE is WATER_COLORS.COLOR; -- противоречия, связанного с именем типа. COLOR   SIGNAL : LIGHT;   PAINT  : SHADE;begin   SIGNAL := GREEN; -— из пакета TRAFFIC   PAINT  := GREEN; -— из пакета WATER-COLORS end R;

Пример идентификации имени со спецификатором использования:

package D is   Т, U, V : BOOLEAN;end D;procedure P is   package E is      B, W, V : INTEGER;   end E;   procedure Q is      Т, Х : REAL;      use D, E;   begin      -— имя     Т означает Q.Т, not D.T      -— имя     U ознaчaeT D.U      -— имя     В означает Е.В      -— имя     W oзнaчaeT E.W      -— имя     Х означает Q.Х      -— имя неправильно: должно быть использовано D.V или      ...   end Q;begin   ...end P;

Ссылки: видимый раздел 7.2, зона описания 8.1, идентификатор 2.3, имя 4.1, компилируемый модуль 10.1, находиться непосредственно в 8.1, непосредственная видимость 8.3, непосредственная область действия 8.2, область действия 8.2, омоним 8.3, описание 3.1, описание подпрограммы 6.1, пакет 7, Предвыполнение 3.1, 3.9, Предвыполнение не имеет другого эффекта 3.1, распространение 8.1, скрытие 8.3, спецификатор контекста 10.1, спецификация литерала перечисления 3.5.1, элемент описания 3.9.