Справочник Ada 2005
13.3 Операционные и представительные атрибуты
Значения некоторых характеристик, зависящих от реализации, могут быть получены посредством запроса соответствующих операционных или представительных атрибутов. Некоторые из этих атрибутов могут быть заданы с помощью описания_атрибута.
Синтаксис
описание_атрибута ::=
for локальное_имя'имя_атрибута use выражение;
| for локальное_имя'имя_атрибута use имя;
for локальное_имя'имя_атрибута use выражение;
| for локальное_имя'имя_атрибута use имя;
Правила разрешения имен
Для описания_атрибута, задающего атрибут, обозначающий значение, следует использовать форму с выражением. В противном случае, следует использовать форму с именем.
Для описания_атрибута, задающего атрибут, обозначающий значение или объект, ожидаемый тип для выражения или имени соответствует типу атрибута. Для описания_атрибута, задающего атрибут, обозначающий подпрограмму, ожидаемый профиль для имени соответствует требуемому профилю атрибута. Для описания_атрибута, задающего атрибут, обозначающий другой тип сущности, имя должно разрешаться на обозначение сущности соответствующего типа.
Правила легальности
Имя_атрибута разрешено в описании_атрибута только в том случае, если этот международный стандарт это разрешает, или для атрибута, определённого реализацией, если реализация это разрешает. Каждый задаваемый атрибут представляет операционный аспект или аспект представления.
Для описания_атрибута, задающего атрибут, обозначающий подпрограмму, профиль должен соответствовать требуемому профилю атрибута, а конвенция должна быть Ada. Дополнительные требования определены для отдельных атрибутов.
Статическая семантика
Оператор размера — это описание_атрибута, имя_атрибута которого — Size. Подобные определения применяются и к другим задаваемым атрибутам.
Элемент хранения — это адресуемый элемент памяти в машине. Слово — это наибольший объём памяти, который может быть удобно и эффективно обработан аппаратным обеспечением, учитывая модель выполнения реализации. Слово состоит из целого числа элементов памяти.
Машинный скаляр — это объём памяти, который может быть удобно и эффективно загружен, сохранён или обработан аппаратным обеспечением. Машинные скаляры состоят из целого числа элементов памяти. Множество машинно-скалярных значений задаётся реализацией, но должно включать, по меньшей мере, элемент памяти и слово. Машинные скаляры используются для интерпретации пункта_компоненты при применении нестандартного порядка битов.
Определены следующие атрибуты представления: Address, Alignment, Size, Storage_Size и Component_Size.
Для префикса X, обозначающего объект, программную единицу или метку:
X'Address
Обозначает адрес первого элемента памяти, выделенного для X. Для программной единицы или метки это значение относится к машинному коду, связанному с соответствующим телом или оператором. Значение этого атрибута имеет тип System.Address.
Address можно задать для автономных объектов и для программных единиц с помощью описания_атрибута.
Ошибка выполнения
Если Address задан, программист несёт ответственность за обеспечение его корректности; в противном случае, выполнение программы является ошибочным.
Рекомендации по реализации
Для массива X, X'Address должен указывать на первый компонент массива, а не на границы массива.
Рекомендуемый уровень поддержки атрибута Address:
- X'Address должен давать полезный результат, если X является объектом, который алиасирован или имеет тип по ссылке, или является сущностью, чей Address был задан.
- Реализация должна поддерживать инструкции Address для импортированных подпрограмм.
- Этот абзац был удален.
- Если адрес объекта задан, или он импортирован или экспортирован, то реализация не должна выполнять оптимизации, основанные на предположениях об отсутствии алиасов.
ПРИМЕЧАНИЯ
1 Указание имени ссылки в псевдониме Export (см. B.1) для подпрограммы или объекта является альтернативой явного указания адреса времени компоновки, позволяя директиве компоновки разместить подпрограмму или объект в памяти.
2 Правила атрибута Size подразумевают, что для алиасированного объекта X, если X'Size = Storage_Unit, то X'Address указывает на элемент памяти, содержащий все биты X, и только биты X.
Статическая семантика
Для префикса X, обозначающего объект:
X'Alignment
Значение этого атрибута — тип universal_integer, неотрицательное; ноль означает, что объект необязательно выровнен на границе элемента памяти. Если X'Alignment не равен нулю, то X выровнен на границе единицы хранения, и X'Address является целым кратным X'Alignment (то есть, остаток от деления Address на Alignment равен нулю).
Этот абзац был удален.
Alignment можно указать для автономных объектов с помощью описания_атрибута; выражение такого описания должно быть статическим и неотрицательным.
Этот абзац был удален.
Для каждого типа S:
S'Alignment
Значение этого атрибута — тип universal_integer, неотрицательное.
Для объекта X типа S, если S'Alignment не равен нулю, то X'Alignment — ненулевое целое кратное S'Alignment, если не указано иное в представлении элемента.
Alignment можно указать для базовых типов с помощью описания_атрибута; выражение такого описания должно быть статическим и неотрицательным.
Ошибка выполнения
Выполнение программы ошибочно, если задано описание Address, конфликтующее с Alignment.
Для объекта, который не выделяется под управлением реализации, выполнение является ошибочным, если объект не выровнен в соответствии со своим Alignment.
Рекомендации по реализации
Рекомендуемый уровень поддержки атрибута Alignment для типов:
- Реализация должна поддерживать описание Alignment для дискретного типа, типа с плавающей запятой, записи или массива, задавая значение Alignment, равное нулю или степени двойки, при соблюдении следующих условий:
- Реализация необязательно поддерживает описание Alignment для целого типа со знаком, задающее значение Alignment, большее, чем самое большое значение Alignment, когда-либо выбранное по умолчанию реализацией для любого целого типа со знаком. Соответствующее ограничение может быть наложено для модульных целых типов, типов с фиксированной точкой, перечислений, записей и массивов.
- Реализация необязательно поддерживает несоответствующее описание Alignment, которое может позволить создавать объекты элементарного типа, которые нельзя легко загружать и сохранять с помощью доступных машинных инструкций.
- Реализация необязательно поддерживает Alignment, заданный для производного помеченного типа, который не является кратным Alignment родительского типа. Реализация необязательно поддерживает несоответствующее Alignment, заданный для производного немеченного типа по ссылке.
Рекомендуемый уровень поддержки атрибута Alignment для объектов:
- Этот абзац был удален.
- Для самостоятельных объектов библиотечного уровня статически ограниченных подтипов реализация должна поддерживать все выравнивания, поддерживаемые целевым компоновщиком. Например, выравнивание страниц, вероятно, будет поддерживаться для таких объектов, но не для подтипов.
- Для других объектов реализация должна, по крайней мере, поддерживать выравнивания, поддерживаемые для их подтипов, с учетом следующего:
- Реализация не должна поддерживать выравнивания, указанные для объектов типа ссылочного типа или для объектов типов, содержащих связанные подкомпоненты, если указанное выравнивание не является кратным выравниванию подтипа объекта.
ПРИМЕЧАНИЯ
3 Выравнивание — это атрибут, специфичный для подтипа.
Этот абзац был удален.
4 Оператор_компонента, Оператор_размера_компонента или Директива Pack могут переопределять указанное выравнивание.
Статическая семантика
Для префикса X, обозначающего объект:
X'Size
Обозначает размер представления объекта в битах. Значение этого атрибута имеет тип universal_integer.
Размер может быть задан для самостоятельных объектов с помощью определения_атрибута; выражение такого оператора должно быть статическим и его значение неотрицательным.
Рекомендации по реализации
Размер массива объекта не должен включать его границы.
Рекомендуемый уровень поддержки атрибута Size объектов такой же, как и для подтипов (см. ниже), за исключением того, что для связанного элементарного объекта необходимо поддерживать только подтверждающий оператор Size.
- Этот абзац был удален.
Статическая семантика
Для каждого подтипа S:
S'Size
Если S определен, обозначает размер (в битах), который реализация выберет для следующих объектов подтипа S:
- Компонента записи подтипа S, когда тип записи упакован.
- Формальный параметр экземпляра Unchecked_Conversion, который преобразует подтип S в какой-либо другой подтип.
Если S неопределен, значение определяется реализацией. Значение этого атрибута имеет тип universal_integer. Размер объекта не меньше, чем размер его подтипа, за исключением случаев, когда размер объекта определяется оператором Size, оператором_компонента или оператором Component_Size. Размер может быть задан для первых подтипов с помощью определения_атрибута; выражение такого оператора должно быть статическим и его значение неотрицательным.
Требования к реализации
В реализации Boolean'Size должен быть равен 1.
Рекомендации по реализации
Если размер подтипа позволяет эффективно адресовать объекты независимо (см. 9.10) на целевой архитектуре, то размер следующих объектов подтипа должен быть равен размеру подтипа:
- Связанные объекты (включая компоненты).
- Несвязанные компоненты, если размер компоненты не определяется оператором_компонента или оператором Component_Size.
Оператор Size составного подтипа не должен влиять на внутреннюю структуру компонент.
Рекомендуемый уровень поддержки атрибута Size подтипов:
- Размер (если не указан) статического дискретного или фиксированного подтипа должен быть равен количеству битов, необходимых для представления каждого значения, принадлежащего подтипу, с помощью несмещённого представления, оставляя место для знака только в том случае, если подтип содержит отрицательные значения. Если такой подтип является первым подтипом, то реализация должна поддерживать указанный размер для него, отражающий это представление.
- Для подтипа, реализованного с уровнями косвенности, размер должен включать размер указателей, но не размер того, на что они указывают.
- Реализация должна поддерживать оператор Size для дискретного типа, типа с фиксированной точкой, типа записи или типа массива, с учетом следующего:
- Реализация не должна поддерживать оператор Size для типа целого со знаком, задающего размер, превышающий размер самого большого типа целого со знаком, поддерживаемого реализацией в отсутствие оператора размера (то есть, когда размер выбирается по умолчанию). Соответствующее ограничение может быть наложено для типов модульного целого, типов с фиксированной точкой, типов перечисления, типов записей и типов массивов.
- Оператор размера, не соответствующий первому подтипу производного не помеченного типа ссылочного типа, не обязательно должен поддерживаться.
ПРИМЕЧАНИЯ
5 Размер — это атрибут, специфичный для подтипа.
6 Оператор_компонента или Оператор Component_Size могут переопределять указанный размер. Директива pragma Pack не может.
Статическая семантика
Для префикса T, обозначающего объект задачи (после любого неявного разыменования):
T'Storage_Size
Обозначает количество элементов памяти, зарезервированных для задачи. Значение этого атрибута имеет тип universal_integer. Размер хранилища включает размер стека задачи, если он есть. Язык не определяет, включает ли он или нет другое хранилище, связанное с задачей (такое как «блок управления задачей», используемый некоторыми реализациями.) Если задана директива pragma Storage_Size, значение атрибута Storage_Size не меньше указанного значения в директиве.
Директива pragma Storage_Size указывает объем памяти, который необходимо зарезервировать для выполнения задачи.
Синтаксис
Форма директивы pragma Storage_Size:
pragma Storage_Size(выражение);
Директива pragma Storage_Size разрешена только непосредственно внутри определения_задачи.
Правила разрешения имен
Динамическая семантика
Директива pragma Storage_Size обрабатывается при создании объекта типа, определенного непосредственно содержащим определением_задачи. При обработке директивы Storage_Size выражение вычисляется; атрибут Storage_Size вновь созданного объекта задачи не меньше значения выражения.
В момент создания или активации объекта задачи Storage_Error генерируется, если свободной памяти недостаточно для размещения запрошенного Storage_Size.
Статическая семантика
Для префикса X, обозначающего подтип массива или массив объекта (после любого неявного разыменования):
X'Component_Size
Обозначает размер компонентов типа X в битах. Значение этого атрибута имеет тип universal_integer.
Component_Size может быть задан для типов массивов с помощью определения_атрибута; выражение такого оператора должно быть статическим и его значение неотрицательным.
Рекомендации по реализации
Рекомендуемый уровень поддержки атрибута Component_Size:
- Реализация не должна поддерживать указанные Component_Sizes, меньшие размера подтипа компонента.
- Реализация должна поддерживать указанные Component_Sizes, которые являются множителями и кратными размеру слова. Для таких Component_Sizes массив не должен содержать пробелов между компонентами. Для других Component_Sizes (если поддерживаются) массив не должен содержать пробелов между компонентами при также указанной упаковке; реализация должна запрещать это сочетание в случаях, когда она не может поддерживать представление без пробелов.
Статическая семантика
Определяется следующий операционный атрибут: External_Tag.
Для каждого подтипа S помеченного типа T (специфического или глобального для класса):
S'External_Tag
S'External_Tag обозначает внешнее строковое представление для S'Tag; оно имеет предопределённый тип String. External_Tag может быть задан для конкретного помеченного типа с помощью описания_атрибута; выражение такого описания должно быть статическим. Представление внешнего тега по умолчанию определяется реализацией. См. 3.9.2 и 13.13.2. Значение External_Tag никогда не наследуется; значение по умолчанию всегда используется, если для типа не указано новое значение.
Требования к реализации
В реализации значение внешнего тега по умолчанию для каждого конкретного помеченного типа, объявленного в разделе, должно быть различным, до тех пор, пока тип объявлен вне экземпляра обобщённого тела. Если единица компиляции, в которой объявлен данный помеченный тип, и все единицы компиляции, от которых она семантически зависит, одинаковы в двух разных разделах, то внешний тег для типа должен быть одинаковым в двух разделах. Что означает, что единица компиляции одинакова в двух разных разделах, определяется реализацией. Как минимум, если единица компиляции не перекомпилируется между построением двух разных разделов, которые её включают, то единица компиляции считается одинаковой в двух разделах.
ПРИМЕЧАНИЯ
7 Следующие определённые языком атрибуты могут быть заданы, по крайней мере, для некоторых типов сущностей, к которым они применяются: Address, Alignment, Bit_Order, Component_Size, External_Tag, Input, Machine_Radix, Output, Read, Size, Small, Storage_Pool, Storage_Size, Stream_Size и Write.
8 Из общих правил в 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
ПРИМЕЧАНИЯ
9 Примечания к примерам: В предложении Size для Short пятнадцать бит — это минимальное необходимое значение, так как определение типа требует Short'Small <= 2**(–7).