Справочник по Ada 2012
13.3 Операционные и представительные атрибуты
Значения некоторых характеристик, зависящих от реализации, можно получить, обратившись к соответствующим операционным или представительным атрибутам. Некоторые из этих атрибутов можно указать с помощью определения_атрибута.
Синтаксис
определение_атрибута ::=
for имя_локальной_переменной'имя_атрибута use выражение;
| for имя_локальной_переменной'имя_атрибута use идентификатор;
for имя_локальной_переменной'имя_атрибута use выражение;
| for имя_локальной_переменной'имя_атрибута use идентификатор;
Правила разрешения имен
Для определения_атрибута, задающего атрибут, обозначающий значение, следует использовать форму с выражением. В противном случае следует использовать форму с идентификатором.
Для определения_атрибута, задающего атрибут, обозначающий значение или объект, ожидаемый тип для выражения или идентификатора — тип атрибута. Для определения_атрибута, задающего атрибут, обозначающий подпрограмму, ожидаемый профиль для идентификатора — профиль, требуемый для атрибута. Для определения_атрибута, задающего атрибут, обозначающий какой-либо другой вид сущности, идентификатор должен ссылаться на сущность соответствующего вида.
Правила допустимости
Именователь_атрибута разрешается в определении_атрибута только в том случае, если это прямо разрешено данным международным стандартом или для атрибута, определяемого реализацией, если это разрешено реализацией. Каждый указываемый атрибут представляет собой операционный аспект или аспект представления; имя аспекта — имя атрибута.
Для определения_атрибута, задающего атрибут, обозначающий подпрограмму, профиль должен быть совместим по режиму с профилем, требуемым для атрибута, и конвенция должна быть Ada. Дополнительные требования определены для отдельных атрибутов.
Статическая семантика
Оператор размера — это определение_атрибута, имеющий имя_атрибута, равный Size. Аналогичные определения применяются и к другим указываемым атрибутам.
Элемент хранения — это адресуемый элемент памяти в машине. Слово — это наибольший объём памяти, который может быть удобно и эффективно обработан аппаратным обеспечением, учитывая модель выполнения реализации. Слово состоит из целого числа элементов хранения.
Машинный скаляр — это объём памяти, который может быть удобно и эффективно загружен, сохранён или обработан аппаратным обеспечением. Машинные скаляры состоят из целого числа элементов хранения. Множество машинно скаляров определяется реализацией, но включает по меньшей мере элемент хранения и слово. Машинные скаляры используются для интерпретации элементов_компонента, когда применяется нестандартный порядок битов.
Определены следующие атрибуты представления: Address, Alignment, Size, Storage_Size, Component_Size, Has_Same_Storage и Overlaps_Storage.
Для префикса X, обозначающего объект, программную единицу или метку:
X'Address
Обозначает адрес первого из элементов хранения, выделенных для X. Для программной единицы или метки это значение относится к машинному коду, связанному с соответствующим телом или выражением. Значение этого атрибута имеет тип System.Address.
Префикс X'Address не должен статически обозначать подпрограмму с конвенцией Intrinsic. X'Address вызывает исключение Program_Error, если X обозначает подпрограмму с конвенцией Intrinsic.
Адрес может быть указан для автономных объектов и программных единиц с помощью определения_атрибута.
Ошибка выполнения
Если задан адрес, программист несёт ответственность за то, чтобы адрес был корректным и соответствующим сущности и её использованию; в противном случае выполнение программы является ошибочным.
Рекомендации по реализации
Для массива X, X'Address должен указывать на первый компонент массива, а не на границы массива.
Рекомендуемый уровень поддержки атрибута Address:
- X'Address должен давать полезный результат, если X — это объект, на который есть ссылка или имеющий тип по ссылке, или это сущность, адрес которой был указан.
- Реализация должна поддерживать предложения Address для импортируемых подпрограмм.
- Этот абзац был удалён.
- Если адрес объекта задан или он импортирован или экспортирован, то реализация не должна выполнять оптимизации, основанные на предположении отсутствия ссылок.
ПРИМЕЧАНИЯ
2 Указание имени связи с аспектом Link_Name (см. B.1) для подпрограммы или объекта является альтернативой явном указанию её адреса во время компоновки, позволяя директиве компоновки разместить подпрограмму или объект в памяти.
3 Правила для атрибута Size подразумевают, что для объекта X со ссылкой, если X'Size = Storage_Unit, то X'Address указывает на элемент хранения, содержащий все биты X, и только биты X.
Статическая семантика
Для префикса X, обозначающего объект:
X'Alignment
Значение этого атрибута — целое неотрицательное число типа universal_integer; ноль означает, что объект необязательно выровнен по границе элемента хранения. Если X'Alignment не ноль, то X выровнен по границе единицы хранения, а X'Address — целое кратное X'Alignment (то есть, остаток от деления Address на Alignment равен нулю).
Этот абзац был удалён.
Выравнивание может быть указано для автономных объектов с помощью определения_атрибута; выражение такого предложения должно быть статическим и неотрицательным.
Этот абзац был удалён.
Для каждого типа S:
S'Alignment
Значение этого атрибута — целое неотрицательное число типа universal_integer.
Для объекта X типа S, если S'Alignment не ноль, то X'Alignment — ненулевое целое кратное S'Alignment, если не указано иное пунктом представления.
Выравнивание может быть указано для типов-сущностей с помощью определения_атрибута; выражение такого предложения должно быть статическим и неотрицательным.
Ошибка выполнения
Выполнение программы ошибочно, если задано предложение Address, которое противоречит выравниванию.
Для объекта, который не выделяется под управлением реализации, выполнение является ошибочным, если объект не выровнен в соответствии со своим выравниванием.
Рекомендации по реализации
Для любого помеченного специализированного типа S, S'Class'Alignment должен быть равен S'Alignment.
Рекомендуемый уровень поддержки атрибута Alignment для типов:
- Реализация должна поддерживать предложение Alignment для дискретного типа, типа с плавающей точкой, записи или массива, определяя значение выравнивания, которое равно нулю или степени двойки, с учётом следующего:
- Реализация может не поддерживать предложение Alignment для целого со знаком, определяющее значение выравнивания, большее, чем наибольшее значение выравнивания, которое когда-либо выбирается по умолчанию реализацией для любого целого со знаком. Соответствующее ограничение может быть наложено для типов целых чисел по модулю, типов с плавающей точкой, перечислений, записей и массивов.
- Реализация может не поддерживать предложение Alignment, не соответствующее профилю, которое может позволить создать объект элементарного типа, который нельзя легко загрузить и сохранить с помощью имеющихся машинных инструкций.
- Реализация может не поддерживать выравнивание, заданное для производного помеченного типа, которое не является кратным выравниванию родительского типа. Реализация может не поддерживать несоответствующее выравнивание, заданное для производного непомеченного типа по ссылке.
Рекомендуемый уровень поддержки атрибута Alignment для объектов:
- Этот абзац был удалён.
- Для автономных объектов на уровне библиотеки статически ограниченных подтипов, реализация должна поддерживать все выравнивания, поддерживаемые целевым линковщиком. Например, выравнивание по страницам, вероятно, будет поддерживаться для таких объектов, но не для подтипов.
- Для других объектов реализация должна, по крайней мере, поддерживать выравнивания, поддерживаемые для их подтипа, с учётом следующего:
- Реализация не обязана поддерживать выравнивания, указанные для объектов типа по ссылке или для объектов типов, содержащих алиасированные подкомпоненты, если указанное выравнивание не является кратным выравниванию подтипа объекта.
ПРИМЕЧАНИЯ
4 Атрибут Alignment — это атрибут, специфичный для подтипа.
Этот абзац был удалён.
5 component_clause, раздел Component_Size или указание аспекта Pack как True могут переопределить заданное выравнивание.
Статическая семантика
Для префикса X, обозначающего объект:
X'Size
Обозначает размер представления объекта в битах. Значение этого атрибута имеет тип universal_integer.
Размер может быть задан для автономных объектов с помощью attribute_definition_clause; выражение такого раздела должно быть статическим и его значение неотрицательным.
Рекомендации по реализации
Размер объекта массива не должен включать его границы.
Рекомендуемый уровень поддержки атрибута Size для объектов такой же, как для подтипов (см. ниже), за исключением того, что для алиасированного элементарного объекта необходимо поддерживать только подтверждающий раздел Size.
- Этот абзац был удалён.
Статическая семантика
Для каждого подтипа S:
S'Size
Если S определён, обозначает размер (в битах), который реализация выберет для следующих объектов подтипа S:
Компонента записи подтипа S, когда тип записи упакован.
Формальный параметр экземпляра Unchecked_Conversion, который преобразует из подтипа S в какой-либо другой подтип.
Если S неопределён, значение определяется реализацией. Значение этого атрибута имеет тип universal_integer. Размер объекта не меньше размера его подтипа, за исключением случаев, когда размер объекта определяется разделом Size, component_clause или Component_Size clause. Размер может быть указан для первых подтипов с помощью attribute_definition_clause; выражение такого раздела должно быть статическим и его значение неотрицательным.
Требования к реализации
В реализации Boolean'Size должен быть равен 1.
Рекомендации по реализации
Если размер подтипа позволяет эффективно получить независимый адрес (см. 9.10) на целевой архитектуре, то размер следующих объектов подтипа должен быть равен размеру подтипа:
- Алиасированные объекты (включая компоненты).
- Неалиасированные компоненты, если размер компонента не определён с помощью component_clause или раздела Component_Size.
Раздел Size для составного подтипа не должен влиять на внутреннюю структуру компонентов.
Рекомендуемый уровень поддержки атрибута Size подтипов:
- Размер (если не задан) статического дискретного или фиксированного подтипа должен быть равен числу битов, необходимых для представления каждого значения, принадлежащего подтипу, с помощью несмещённого представления, оставляя место для бита знака только в том случае, если подтип содержит отрицательные значения. Если такой подтип является первым подтипом, то реализация должна поддерживать указанный размер, отражающий это представление.
- Для подтипа, реализованного с уровнями косвенности, размер должен включать размер указателей, но не размер того, на что они указывают.
- Реализация должна поддерживать раздел Size для дискретного типа, фиксированного типа, типа записи или типа массива, с учётом следующего:
Реализация не обязана поддерживать раздел Size для целого типа со знаком, определяющего размер, превышающий размер самого большого целого типа со знаком, поддерживаемого реализацией без раздела size (то есть, когда размер выбирается по умолчанию). Соответствующее ограничение может быть наложено для модулярных целочисленных типов, фиксированных типов, типов перечислений, типов записей и типов массивов.
Раздел size, не соответствующий первому подтипу производного не помеченного типа по ссылке, не обязательно должен поддерживаться.
ПРИМЕЧАНИЯ
6 Размер — это атрибут, специфичный для подтипа.
7 component_clause или раздел Component_Size могут переопределить указанный размер. Аспект Pack не может.
Статическая семантика
Для префикса T, обозначающего объект задачи (после любого неявного разыменования):
T'Storage_Size
Обозначает количество элементов памяти, зарезервированных для задачи. Значение этого атрибута имеет тип universal_integer. Размер Storage_Size включает размер стека задачи, если таковой имеется. Язык не определяет, включает ли он другой объём памяти, связанный с задачей (например, «блок управления задачей», используемый некоторыми реализациями). Если аспект Storage_Size задан для типа объекта, значение атрибута Storage_Size не меньше значения, определённого аспектом.
Аспект Storage_Size определяет объём памяти, который необходимо зарезервировать для выполнения задачи.
Абзацы с 62 по 65 были перемещены в Приложение J, «Устаревшие возможности».
Статическая семантика
Для типа задачи (включая анонимный тип single_task_declaration), может быть задан следующий язык-определённый аспект представления:
Storage_Size
Аспект Storage_Size — это выражение, которое должно быть любого целочисленного типа.
Правила легитимности
Аспект Storage_Size не должен быть задан для типа интерфейса задачи.
Динамическая семантика
При создании объекта задачи выражение (если есть) ассоциированное с аспектом Storage_Size его типа вычисляется; атрибут Storage_Size вновь созданного объекта задачи не меньше значения выражения.
В момент создания объекта задачи или при активации задачи, Storage_Error поднимается, если свободной памяти недостаточно для размещения запрошенного Storage_Size.
Статическая семантика
Для префикса X, обозначающего подтип массива или объект массива (после любого неявного разыменования):
X'Component_Size
Обозначает размер компонентов типа X в битах. Значение этого атрибута имеет тип universal_integer.
Component_Size может быть задан для типов массивов с помощью attribute_definition_clause; выражение такого раздела должно быть статическим и его значение неотрицательным.
Рекомендации по реализации
Рекомендуемый уровень поддержки атрибута Component_Size:
- Реализация не обязана поддерживать указанные Component_Sizes, которые меньше размера подтипа компонента.
- Реализация должна поддерживать указанные Component_Sizes, которые являются факторами и кратными размеру слова. Для таких Component_Sizes массив не должен содержать пробелов между компонентами. Для других Component_Sizes (если поддерживаются), массив не должен содержать пробелов между компонентами, когда также указан аспект Pack; реализация должна запрещать эту комбинацию в тех случаях, когда она не может поддерживать представление без пробелов.
Статическая семантика
Для префикса X, обозначающего объект:
X'Has_Same_Storage
X'Has_Same_Storage обозначает функцию со следующим описанием:
function X'Has_Same_Storage (Arg : any_type)
return Boolean
return Boolean
Фактический параметр должен быть именем, обозначающим объект. Объект, обозначаемый фактическим параметром, может быть любого типа. Эта функция оценивает имена вовлечённых объектов. Она возвращает True, если представление объекта, обозначаемого фактическим параметром, занимает ровно те же биты, что и представление объекта, обозначаемого X, и объекты занимают по крайней мере один бит; в противном случае возвращает False.
Для префикса X, обозначающего объект:
X'Overlaps_Storage
X'Overlaps_Storage обозначает функцию со следующим описанием:
function X'Overlaps_Storage (Arg : any_type)
return Boolean
return Boolean
Фактический параметр должен быть именем, обозначающим объект. Объект, обозначаемый фактическим параметром, может быть любого типа. Эта функция оценивает имена вовлеченных объектов и возвращает True, если представление объекта, обозначаемого фактическим параметром, имеет хотя бы один совпадающий бит с представлением объекта, обозначаемого X; в противном случае возвращает False.
ПРИМЕЧАНИЯ
8 X'Has_Same_Storage(Y) подразумевает X'Overlaps_Storage(Y).
9 X'Has_Same_Storage(Y) и X'Overlaps_Storage(Y) не считаются чтением X и Y.
Статическая семантика
Определяется следующее операционное атрибут, связанный с типом: External_Tag.
Для каждого подтипа S помеченного типа T (конкретного или для всего класса):
S'External_Tag
S'External_Tag обозначает внешнее строковое представление для S'Tag; оно имеет предопределённый тип String. External_Tag может быть задан для конкретного помеченного типа с помощью определения_атрибута; выражение такого пункта должно быть статическим. Представление внешнего тега по умолчанию определяется реализацией. См. 13.13.2. Значение External_Tag никогда не наследуется; значение по умолчанию всегда используется, если для типа явно не указано новое значение.
Динамическая семантика
Если заданный пользователем внешний тег S'External_Tag совпадает с T'External_Tag для какого-либо другого помеченного типа, объявленного другим объявлением в разделе, то при разработке определения_атрибута возникает ошибка Program_Error.
Требования к реализации
В реализации значение внешнего тега по умолчанию для каждого конкретного помеченного типа, объявленного в разделе, должно быть различным, пока тип объявлен вне экземпляра тела обобщения. Если единица компиляции, в которой объявлен данный помеченный тип, и все единицы компиляции, от которых он семантически зависит, одинаковы в двух разных разделах, то внешний тег для типа должен быть одинаковым в обоих разделах. Что означает, что единица компиляции одинакова в двух разных разделах, определяется реализацией. Как минимум, если единица компиляции не перекомпилируется между построением двух различных разделов, которые её включают, то единица компиляции считается одинаковой в обоих разделах.
Разрешения для реализации
Если заданный пользователем внешний тег S'External_Tag совпадает с T'External_Tag для какого-либо другого помеченного типа, объявленного другим объявлением в разделе, раздел может быть отклонен.
ПРИМЕЧАНИЯ
10 Следующие определяемые языком атрибуты могут быть заданы, по крайней мере, для некоторых видов сущностей, к которым они применяются: Address, Alignment, Bit_Order, Component_Size, External_Tag, Input, Machine_Radix, Output, Read, Size, Small, Storage_Pool, Storage_Size, Stream_Size и Write.
11 Из общих правил в 13.1 следует, что если написать «for X'Size use Y;», то ссылка на атрибут X'Size attribute_reference вернёт Y (при условии, что реализация допускает пункт Size). То же самое верно для всех задаваемых атрибутов, кроме Storage_Size.
Примеры
Примеры пунктов определения атрибутов:
Byte : constant := 8;
Page : constant := 2**12;
Page : constant := 2**12;
type Medium is range 0 .. 65_000;
for Medium'Size use 2*Byte;
for Medium'Alignment use 2;
Device_Register : Medium;
for Device_Register'Size use Medium'Size;
for Device_Register'Address use System.Storage_Elements.To_Address(16#FFFF_0020#);
for Medium'Size use 2*Byte;
for Medium'Alignment use 2;
Device_Register : Medium;
for Device_Register'Size use Medium'Size;
for Device_Register'Address use System.Storage_Elements.To_Address(16#FFFF_0020#);
type Short is delta 0.01 range -100.0 .. 100.0;
for Short'Size use 15;
for Short'Size use 15;
for Car_Name'Storage_Size use -- укажите размер пула хранения типа доступа
2000*((Car'Size/System.Storage_Unit) +1); -- приблизительно 2000 автомобилей
2000*((Car'Size/System.Storage_Unit) +1); -- приблизительно 2000 автомобилей
function My_Input(Stream : not null access Ada.Streams.Root_Stream_Type'Class)
return T;
for T'Input use My_Input; -- см. 13.13.2
return T;
for T'Input use My_Input; -- см. 13.13.2
ПРИМЕЧАНИЯ
12 Примечания к примерам: В пункте Size для Short 15 бит является минимально необходимым, так как определение типа требует Short'Small <= 2**(–7).