Spec-Zone.ru › Ada 95
Справочник по Ada 95

3.10.2 Операции типов доступа

Атрибут Access используется для создания значений доступа, обозначающих объекты с алиасами и неинтринсивные подпрограммы. Правила «доступности» предотвращают висячие ссылки (в отсутствие использования определенных небезопасных функций — см. раздел 13).

Правила разрешения имен

Для attribute_reference с attribute_designator Access (или Unchecked_Access — см. 13.10) ожидаемый тип должен быть единственным типом доступа; prefix такого attribute_reference никогда не интерпретируется как implicit_dereference. Если ожидаемый тип — тип доступа к подпрограмме, то ожидаемый профиль prefix — профиль указанного типа доступа.

Статическая семантика

Правила доступности, которые предотвращают висячие ссылки, записываются в терминах уровней доступности, отражающих временную вложенность мастеров. Как объяснено в 7.6.1, мастер — это выполнение task_body, block_statement, subprogram_body, entry_body или accept_statement. Уровень доступности глубее другого, если он более глубоко вложен во время выполнения. Например, объект, объявленный локально в вызываемой подпрограмме, имеет более глубокий уровень доступности, чем объект, объявленный локально в вызывающей подпрограмме. Правила доступности для типов доступа требуют, чтобы уровень доступности объекта, обозначенного значением доступа, не был глубже уровня доступности типа доступа. Это гарантирует, что объект будет существовать как минимум так же долго, как и тип доступа, что, в свою очередь, гарантирует, что значение доступа не сможет позднее обозначить объект, который больше не существует. Атрибут Unchecked_Access может использоваться для обхода правил доступности.
Говорят, что данный уровень доступности статически глубже другого, если данный уровень известен во время компиляции (как определено ниже) как глубже другого для всех возможных выполнений. В большинстве случаев доступность обеспечивается на этапе компиляции с помощью Правил законности. Также используются проверки доступности во время выполнения, так как Правила законности не охватывают определенные случаи, связанные с параметрами доступа и обобщенными пакетами.
Каждый мастер, а также каждый созданный им элемент и представление, имеет уровень доступности:
  • Уровень доступности данного мастера глубже, чем у каждого динамически содержащего его мастера, и глубже, чем у каждого мастера, от которого непосредственно зависит задача, выполняющая данный мастер (см. 9.3).
  • Элемент или представление, созданные объявлением, имеют тот же уровень доступности, что и самый внутренний содержащий мастер, за исключением случаев переименования и производных типов доступа, описанных ниже. Параметр мастера имеет тот же уровень доступности, что и мастер.
  • Уровень доступности представления объекта или подпрограммы, определенного renaming_declaration, такой же, как и у переименованного представления.
  • Уровень доступности преобразования представления такой же, как у операнда.
  • Для функции, результат которой — тип возвращаемого по ссылке значения, уровень доступности результата — такой же, как у мастера, который обработал тело функции. Для любой другой функции уровень доступности результата — уровень выполнения вызываемой функции.
  • Уровень доступности производного типа доступа — такой же, как у его конечного предка.
  • Уровень доступности анонимного типа доступа дискриминанта доступа — такой же, как у содержащего объекта или связанного ограниченного подтипа.
  • Уровень доступности анонимного типа доступа параметра доступа — такой же, как у представления, обозначенного фактическим значением. Если фактическое значение — allocator, то это уровень доступности выполнения вызываемой подпрограммы.
  • Уровень доступности объекта, созданного allocator, такой же, как у типа доступа.
  • Уровень доступности представления объекта или подпрограммы, обозначенного разыменованием значения доступа, такой же, как у типа доступа.
  • Уровень доступности компонента, защищенной подпрограммы или входа (представления) составного объекта такой же, как у (представления) составного объекта.
Один уровень доступности определен как статически глубже другого в следующих случаях:
  • Для мастера, который статически вложен в другой мастер, уровень доступности внутреннего мастера статически глубже, чем уровень внешнего мастера.
  • Отношение статической глубины не относится к уровню доступности анонимного типа параметра доступа; такой уровень доступности не считается статически глубже или статически мельче любого другого.
  • Для определения, является ли один уровень статически глубже другого внутри тела обобщенного пакета, предполагается, что обобщенный пакет инстанцируется на том же уровне, где он был объявлен; для более глубоко вложенных инстанциаций требуются проверки во время выполнения.
  • Для определения, является ли один уровень статически глубже другого внутри области объявления type_declaration, предполагается, что текущий экземпляр типа — это объект, созданный на уровне глубже, чем уровень типа.
Уровень доступности всех библиотечных модулей называется уровнем библиотеки; библиотечное объявление или элемент — это такой, уровень доступности которого — уровень библиотеки.
Следующий атрибут определен для prefix X, который обозначает представленный с алиасом объект:
X'Access
X'Access возвращает значение доступа, обозначающее объект, обозначенный X. Тип X'Access — это тип доступа к объекту, определяемый ожидаемым типом. Ожидаемый тип должен быть общим типом доступа. X должен обозначать представление с алиасом объекта, включая, возможно, текущий экземпляр (см. 8.6) ограниченного типа внутри его определения, или формальный параметр или обобщенный формальный объект помеченного типа. Представление, обозначенное prefix X, должно удовлетворять следующим дополнительным требованиям, предполагая, что ожидаемый тип для X'Access — это общий тип доступа A с типом обозначения D:
  • Если A — это тип доступа к переменной, то представление должно быть переменной; с другой стороны, если A — это тип доступа к константе, то представление может быть либо константой, либо переменной.
  • Представление не должно быть подкомпонентом, зависящим от дискриминантов переменной, номинальный подтип которой не ограничен, если этот подтип не определен, или переменная имеет алиас.
  • Если A — это именованный тип доступа, а D — это помеченный тип, то тип представления должен быть покрыт D; если A анонимный и D помеченный, то тип представления должен быть либо D'Class, либо тип, покрытый D; если D неопознан, то тип представления должен быть D, и подтип обозначения A должен либо статически соответствовать номинальному подтипу представления, либо быть дискриминированным и не ограниченным;
  • Уровень доступности представления не должен быть статически глубже уровня доступности типа доступа A. В дополнение к местам, где обычно применяются Правила законности (см. 12.3), это правило применяется также в частях с закрытым доступом экземпляра обобщенного модуля.
Проверяется, что уровень доступности X не глубже уровня доступности типа A. Если проверка не проходит, поднимается Program_Error.
Если номинальный подтип X не статически соответствует обозначенному подтипу A, оценивается преобразование представления X к обозначенному подтипу (что может вызвать Constraint_Error — см. 4.6), и значение X'Access обозначает это представление.
Следующий атрибут определен для prefix P, обозначающего подпрограмму:
P'Access
P'Access возвращает значение доступа, обозначающее подпрограмму, обозначенную P. Тип P'Access — это тип доступа к подпрограмме (S), определяемый ожидаемым типом. Уровень доступности P не должен быть статически глубже, чем уровень доступности S. В дополнение к местам, где обычно применяются Правила законности (см. 12.3), это правило применяется также в частях с закрытым доступом экземпляра обобщенного модуля. Профиль P должен быть совместим с подтипом обозначенного профиля S и не должен быть интринсивным. Если подпрограмма, обозначенная P, объявлена внутри тела обобщенного модуля, S должно быть объявлено внутри тела обобщенного модуля.
ПРИМЕЧАНИЯ
81 Атрибут Unchecked_Access возвращает тот же результат, что и атрибут Access для объектов, но имеет меньше ограничений (см. 13.10). Существуют и другие предопределенные операции, которые возвращают значения доступа: allocator может быть использован для создания объекта и возврата значения доступа, обозначающего его (см. 4.8); вычисление литерала null возвращает значение доступа null, которое не обозначает никакого объекта вообще (см. 4.2).
82 Предопределённые операции типа доступа также включают операцию присваивания, квалификацию и проверки принадлежности. Явное преобразование разрешено между общими типами доступа с соответствующими назначенными подтипами; явное преобразование разрешено между типами доступа к подпрограммам с профилями, соответствующими подтипу (см. 4.6). У типов доступа с именами есть предопределённые операторы равенства; у анонимных типов доступа их нет (см. 4.5.2).
83 Объект или подпрограмма, обозначенные значением доступа, могут быть названы с помощью разыменования, либо явным_разыменованием, либо неявным_разыменованием. См. 4.1.
84 Вызов через разыменование значения доступа к подпрограмме никогда не является вызовом с перегрузкой.
85 Правила доступа подразумевают, что нельзя использовать атрибут Access для реализации «замыканий вниз» — то есть передавать более вложенную подпрограмму как параметр менее вложенной подпрограмме, как может потребоваться, например, для абстракции итератора. Вместо этого замыкания вниз можно реализовать с помощью общих формальных подпрограмм (см. 12.6). Обратите внимание, что Unchecked_Access не разрешен для подпрограмм.
86 Обратите внимание, что использование типа доступа к классам с помеченными типами с операцией перегрузки — потенциально более структурированная альтернатива использованию типа доступа к подпрограмме.
87 Реализация может считать два значения доступа к подпрограммам различными, даже если они обозначают одну и ту же подпрограмму. Это может быть потому, что одно указывает непосредственно на подпрограмму, а другое — на специальный пролог, который выполняет Elaboration_Check и затем переходит к подпрограмме. См. 4.5.2.

Примеры

Пример использования атрибута доступа:
Martha : Person_Name := new Person(F); -- см. 3.10.1
Cars : array (1..2) of aliased Car;
...
Martha.Vehicle := Cars(1)'Access;
George.Vehicle := Cars(2)'Access;


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API