Руководство по Ada (Ada 2022)
13.1 Операционные и представленческие аспекты
Можно указать два типа аспектов сущностей: представленческие аспекты и операционные аспекты. Представленческие аспекты влияют на то, как типы и другие сущности языка должны быть отображены на подлежащей машине. Операционные аспекты определяют другие свойства сущностей.
Любой тип аспекта сущности может быть указан с помощью aspect_specification (см. 13.1.1), который является необязательным элементом большинства видов объявлений и применяется к объявляемой сущности или сущностям. Аспекты также могут быть указаны с помощью некоторых других конструкций, следующих за объявлением затронутой сущности: значение представленческого аспекта может быть указано с помощью элемента представления, а значение операционного аспекта может быть указано с помощью операционного элемента.
Существует шесть типов элементов представления: attribute_definition_clause для представленческих атрибутов, enumeration_representation_clause, record_representation_clause, at_clause, component_clause и представленческие pragmas. Они могут быть предоставлены для обеспечения более эффективного представления или для взаимодействия с функциями, которые находятся за пределами области языка (например, периферийным оборудованием).
Операционный элемент представляет собой attribute_definition_clause для операционного атрибута.
Операционный элемент или элемент представления применяются к сущности, идентифицированной local_name, которая обозначает сущность, объявленную локально для текущей области объявления, или библиотечный блок, объявленный непосредственно перед представленческим pragma в compilation.
Синтаксис
aspect_clause ::= attribute_definition_clause
| enumeration_representation_clause
| record_representation_clause
| at_clause
| enumeration_representation_clause
| record_representation_clause
| at_clause
Представленческое pragma разрешено только в местах, где разрешено aspect_clause или compilation_unit.
Правила разрешения имен
В операционном элементе или элементе представления, если local_name является direct_name, то он должен разрешаться в обозначение объявления (или, в случае pragma, одного или нескольких объявлений), которое находится непосредственно внутри той же области объявления, что и элемент. Если local_name имеет attribute_designator, то он должен разрешаться в обозначение определяемого реализацией компонента (см. 13.5.1) или типа всего класса, неявно объявленного непосредственно внутри той же области объявления, что и элемент. local_name, который является library_unit_name (разрешено только в представленческом pragma), должен разрешиться в обозначение library_item, который непосредственно предшествует (кроме других pragmas) представленческому pragma.
Правила легитимности
local_name aspect_clause или представленческого pragms должен статически обозначать сущность (или, в случае pragma, одну или несколько сущностей), объявленную непосредственно перед ним в compilation или внутри той же declarative_part, package_specification, task_definition, protected_definition или record_definition как элемент представления или операционный элемент. Если local_name обозначает локальную вызываемую сущность, она может делать это через локальное subprogram_renaming_declaration (как способ разрешить неоднозначность при наличии перегрузки); в противном случае local_name не должен обозначать renaming_declaration.
Представление объекта состоит из определенного количества битов (размер объекта). Для объекта элементарного типа это биты, которые обычно считываются или обновляются машинным кодом при загрузке, сохранении или обработке значения объекта. Для объекта составного типа это биты, зарезервированные для этого объекта, и включают биты, занимаемые подкомпонентами объекта. Если размер объекта больше, чем размер его подтипа, дополнительные биты являются битами заполнения. Для элементарного объекта эти биты заполнения обычно считываются и обновляются вместе с другими. Для составного объекта не определено, считываются или обновляются ли биты заполнения при выполнении любой составной операции.
Элемент представления непосредственно указывает представленческий аспект сущности, обозначаемой local_name, за исключением случаев представления, связанного с типом, где local_name должен обозначать первый подтип, и который непосредственно указывает аспект типа подтипа. Элемент представления, который называет подтип, является либо специфичным для подтипа (размер, размер объекта и выравнивание), либо связанным с типом (все остальные).
Операционный элемент непосредственно указывает операционный аспект сущности, обозначаемой local_name, за исключением случаев операционного элемента, связанного с типом, где local_name должен обозначать первый подтип, и который непосредственно указывает аспект типа подтипа.
Аспекты, которые могут быть указаны для типов и подтипов, также классифицируются как аспекты, связанные с типом или специфичные для подтипов. Представленческие аспекты, которые могут быть указаны для типов и подтипов, считаются связанными с типом, если не указано иное. Напротив, классификация операционных аспектов дается с определением аспекта. Аспекты, связанные с типом, имеют одно и то же значение для всех подтипов (вида) типа, тогда как аспекты, специфичные для подтипа, могут различаться для разных подтипов одного типа.
Элемент представления или операционный элемент, который непосредственно указывает аспект сущности, должен появиться до того, как сущность заморозится (см. 13.14).
Представленческий аспект подтипа или типа не должен быть указан (ни элементом представления, ни aspect_specification) до того, как тип будет полностью определен (см. 3.11.1).
Если задан элемент представления, операционный элемент, pragma библиотечного блока (см. J.15) или aspect_specification, который непосредственно указывает аспект сущности, то запрещено указывать другой элемент представления, операционный элемент, pragma библиотечного блока или aspect_specification, который непосредственно указывает тот же аспект сущности.
Если не указано иное, запрещено указывать операционный или представленческий аспект формального параметра обобщения.
Примитив по ссылке — это определяемая пользователем примитивная подпрограмма для типа T, которая имеет доступный результат, обозначающий тип T, или которая имеет формальный параметр, который является параметром доступа, обозначающий тип T или является алиасом и типа T. Запрещено указывать несоответствующий аспект представления, связанный с типом для неуказанного типа T, если он получен из типа по ссылке или наследует один или несколько примитивов по ссылке, или если один или несколько типов были получены из T до указания аспекта и тип T является типом по ссылке или определяет один или несколько примитивов по ссылке, которые наследуются этими потомками.
Если для частичного представления типа определён аспект, относящийся к типу, то он имеет такое же определение для полного представления типа, за исключением определённых аспектов, имеющих булево значение, где язык определяет, что частичное представление может иметь значение False, даже если полное представление имеет значение True. Аспекты, относящиеся к типу, не могут быть указаны и не определены для неполного представления типа. Аспекты представления обобщённого формального параметра такие же, как и у фактического. Указание аспекта представления, относящегося к типу, не разрешено для потомка обобщённого формального неупорядоченного типа.
Указание аспекта Size для данного подтипа, или размера или места хранения объекта (включая компонент) данного подтипа, должно обеспечивать достаточно места для хранения любого значения подтипа.
Указание определённых аспектов, определяемых языком, не обязательно должно поддерживаться всеми реализациями; в такой реализации указание такого аспекта является недопустимым или вызывает исключение во время выполнения.
Декларация type_declaration является недопустимой, если она имеет одного или более предков, и для аспекта представления предка было указано несоответствующее значение, и это конфликтует с представлением какого-либо другого предка. Случаи, которые вызывают конфликты, определяются реализацией.
При указании аспекта, обозначающего подпрограмму, профиль подпрограммы должен соответствовать требуемому для аспекта, и соглашение должно быть Ada. Дополнительные требования определены для конкретных аспектов.
Статическая семантика
Если два подтипа статически совпадают, то их аспекты, специфичные для подтипа (например, Size и Alignment), одинаковы.
Производный тип наследует каждый аспект представления, относящийся к типу родительского типа, который был непосредственно указан до объявления производного типа, или (в случае, если родительский тип производный) который был унаследован родительским типом от родительского родительского типа. Производный подтип наследует каждый аспект представления, специфичный для подтипа, родительского подтипа, который был непосредственно указан до объявления производного типа, или (в случае, если родительский тип производный) который был унаследован родительским подтипом от родительского родительского подтипа, но только если родительский подтип статически соответствует первому подтипу родительского типа. Унаследованный аспект представления переопределяется последующим aspect_specification или элементом представления, которые указывают другое значение для того же аспекта типа или подтипа.
Напротив, наследуются ли операционные аспекты, относящиеся к типу, производным типом, зависит от каждого конкретного аспекта; если не указано иное, операционный аспект не наследуется. Когда операционные аспекты, относящиеся к типу, наследуются производным типом, аспекты, которые были непосредственно указаны aspect_specification или операционными элементами, которые видны в любой момент в пределах непосредственной области действия объявления производного типа, или (в случае, если родительский тип производный) которые были унаследованы родительским типом от родительского родительского типа, наследуются. Унаследованный операционный аспект переопределяется aspect_specification или операционным элементом, которые указывают тот же аспект типа.
Когда наследуется операционный аспект, относящийся к типу, правила наследования зависят от природы аспекта (см. 13.1.1). Если не указано иное для данного аспекта, эти правила таковы:
- Для операционного аспекта, представляющего собой значение, наследуемый аспект имеет то же значение;
- Для операционного аспекта, представляющего собой имя:
если имя обозначает одну или несколько примитивных подпрограмм типа, наследуемый аспект — это имя, которое обозначает соответствующую(ие) примитивную(ые) подпрограмму(ы) производного типа;
в противном случае, наследуемый аспект — это имя, которое обозначает ту же(ие) сущность(и), что и исходный аспект;
- Для операционного аспекта, представляющего собой идентификатор, специфичный для аспекта, наследуемый аспект — тот же идентификатор;
- Для операционного аспекта, представляющего собой выражение или агрегат, наследуемый аспект — соответствующее выражение или агрегат, где каждое имя, значение и идентификатор следуют тем же правилам наследования.
Каждый аспект представления сущности следующий:
- Если аспект указан для сущности, то есть он либо непосредственно указан, либо унаследован, то этот аспект сущности такой, как указано, за исключением Storage_Size, который указывает минимум.
- Если аспект представления сущности не указан, он выбирается по умолчанию не указанным образом.
Если операционный аспект указан для сущности (что означает, что он либо непосредственно указан, либо, если связанный с типом или подтипом, унаследован), то этот аспект сущности такой, как указано. В противном случае аспект сущности имеет значение по умолчанию для этого аспекта. Для аспектов, которые не являются связанными с типом или подтипом, термины «указан» и «непосредственно указан» эквивалентны.
aspect_specification или элемент представления, которые указывают аспект представления, который был бы выбран в отсутствие aspect_specification или элемента представления, называется подтверждающим. Значение аспекта, указанное в этом случае, называется подтверждающим значением аспекта представления. Другие значения аспекта называются неподтверждающими, как и aspect_specification и элементы представления, которые их указали. Аналогично, aspect_specification или операционный элемент, который указывает операционный аспект таким же, как определение, которое он имеет по умолчанию, называется подтверждающим; в противном случае он является неподтверждающим.
Динамическая семантика
При разработке aspect_clause вычисляются любые вычисляемые конструкции в нём.
Разрешения реализации
Реализация может интерпретировать аспекты представления произвольным способом. Реализация может наложить ограничения на указание аспектов представления. Рекомендованный уровень поддержки определяется для указания аспектов представления и смежных функций в каждом подпункте. Эти рекомендации меняются на требования для реализаций, поддерживающих приложение программирования систем (см. C.2, «Требуемая поддержка представления»).
Рекомендации для реализации
Рекомендуемый уровень поддержки для указания всех аспектов представления квалифицируется следующим образом:
- Поддержка подтверждающего указания аспекта представления должна быть обеспечена.
- Реализация не обязана поддерживать указание аспекта представления, содержащего нестатические выражения, если каждое нестатическое выражение является именем, которое статически обозначает константу, объявленную перед сущностью.
- Реализация не обязана поддерживать указание Object_Size или Size для данного составного подтипа, а также размера или места хранения объекта (включая компонент) данного составного подтипа, если все ограничения на подтип и его составные подкомпоненты (при наличии) являются статическими ограничениями.
- Реализация не обязана поддерживать указание неподтверждающего значения аспекта представления, если это может привести к тому, что связанный объект или объект типа по ссылке будет выделен по неадресуемому расположению или, если атрибут выравнивания подтипа такого объекта не равен нулю, по адресу, который не является целым кратным этого выравнивания.
- Реализация не обязана поддерживать указание неподтверждающего значения аспекта представления, если это может привести к тому, что связанный объект элементарного типа будет иметь размер, отличный от того, который был бы выбран по умолчанию.
- Реализация не обязана поддерживать указание неподтверждающего значения аспекта представления, если это может привести к тому, что связанный объект составного типа или объект, тип которого является по ссылке, будет иметь размер меньше, чем тот, который был бы выбран по умолчанию.
- Реализация не обязана поддерживать указание неподтверждающего значения аспекта представления, специфичного для подтипа, для неопределённого или абстрактного подтипа.
В целях этих правил определение того, может ли указание значения аспекта представления для типа привести к тому, что объект будет иметь какое-либо свойство, основано исключительно на свойствах самого типа, а не на любой доступной информации о том, как тип используется. В частности, предполагается, что минимально выровненные объекты этого типа могут быть объявлены в какой-то момент.
ПРИМЕЧАНИЕ. Аспекты, которые могут быть указаны, определены в этом документе и обобщены в K.1.