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

Для любого объекта, программного модуля, метки или входа X:

X'ADDRESS Вырабатывает адрес первого кванта памяти, отведенной под X. Для подпрограммы, пакета, задачного модуля или метки это значе­ние ссылается на машинный код, связанный с соответствующим телом или оператором. Для входа, для которого задан спецификатор адреса, это зна­чение ссылается на соответствующее аппаратное прерывание. Значение этого атрибута принадлежит типу ADDRESS, определенному в пакете SYSTEM.

Для любого типа или подтипа X или для любого объекта X:

X’SIZE Примененный к объекту вырабатывает число битов, отводимых в памяти для размещения объекта. Примененный к типу или подтипу выра­батывает минимальное число битов, необходимое реализации для размеще­ния любого возможного объекта этого типа или подтипа. Значение этого ат­рибута имеет типуниверсальный_целый.

Если префиксом атрибута является функция, то атрибут понимается как атрибут функции (а не результата вызова функции). Если тип префик­са — ссылочный тип, то атрибут понимается как атрибут префикса (а не указанного объекта: атрибуты этого объекта могут быть записаны с пре­фиксом, оканчивающимся зарезервированным словом all).

Для любого компонента К записи 3:

3 .IMPOSITION Вырабатывает величину смещения первого кванта памя­ти, занятого полем К, относительно начала первого кванта памяти, занятого записью 3. Величина смещения измеряется числом квантов памяти. Значе­ние этого атрибута принадлежит универсальному_целому типу.

3.K'FIRST_BIT Вырабатывает величину смещения первого бита, занято­го полем К, относительно начала первого кванта памяти, занятого К. Вели­чина смещения измеряется числом битов. Значение этого атрибута имеет универсальный—целый тип.

3.K'LAST_BIT Вырабатывает величину смещения последнего бита, за­нятого полем К, относительно начала первого кванта памяти, занятого К. Величина смещения измеряется числом битов. Значение этого атрибута име­ет универсальный _целый тип.

Для любого ссылочного типа или подтипа Т:

T'STORAGE_SIZE Вырабатывает общее число квантов памяти, выде­ленных для набора, связанного с базовым типом Т. Значение атрибута име­ет универсальный _целый тип.

Для любого заданного типа или объекта заданного типа Т:

T'STORAGE—SIZE Вырабатывает число квантов памяти, выделенных для каждой активизации задачи типа Т или для активизации объекта Т за­данного типа. Значение этого атрибута имеет универсальный_целый тип.

Примечание. Для объекта X заданного типа атрибут X'SIZE вырабатывает число разрядов, используемых для размещения объекта X; атрибут X'STORAGE_SIZE выра­батывает число квантов памяти, выделенных для активизации задачи, указанной X. Для формального параметра X в случае передачи параметра копированием X'ADDRESS вырабатывает адрес локальной копии; в случае передачи параметра ссылкой X'ADDRESS вырабатывает адрес фактического параметра.

  1. . А т р и б у т ы представления вещественных ти­пов

Для каждого вещественного типа или подтипа Т определены нижеследу­ющие машинно-зависимые атрибуты, не связанные с модельными числами. Использующие эти атрибуты программы могут получить некоторую допол­нительную информацию о характеристиках числового типа (см. разд. 4.5.7 о правилах определения точности операций с вещественными операндами). Для обеспечения переносимости программ должна быть обеспечена извест­ная осторожность в использовании таких машинно-зависимых атрибутов.

Атрибуты, применимые к плавающим и фиксированным типам:

T'MACHINE_ROUNDS Вырабатывает значение TRUE, если каждая пре­допределенная арифметическая операция над значениями базового типа Т либо возвращает точный результат, либо осуществляет округление. В про­тивном случае вырабатывает значение FALSE. Значение этого атрибута име­ет предопределенный тип BOOLEAN.

T’MACHINE_OVERFLOWS Вырабатывает значение TRUE, если каждая предопределенная операция над значениями базового типа Т либо возвра­щает точный результат, либо возбуждает исключение NUMERIC_ERROR при переполнении (см. разд. 4.5.7); в противном случае вырабатывает значение FALSE. Значение этого атрибута имеет предопределенный тип BOOLEAN.

Следующие атрибуты дают характеристики машинного представления значений плавающего типа в терминах канонической формы, определенной в разд. 3.5.7:

T'MACHINE_RADIX Вырабатывает значение основания системы счисле­ния, используемого в машинном представлении базового типа Т. Значение этого атрибута имеет универсальный _целый тип.

T'MACHINE_MANTISSA Вырабатывает число цифр в мантиссе машин­ного представления базового типа Т. (Цифра — это расширенная цифра из диапазона от 0 до T'MACHINE_RADIX-1.) Значение этого атрибута имеет универсальный „целый тип.

T'MACHINE—ЕМАХ Вырабатывает наибольшее значение порядка в ма­шинном представлении базового типа Т. Значение этого атрибута имеет универсальный_ целый тип.

T'MACHINE_EMIN Вырабатывает наименьшее (наибольшее по модулю отрицательное) значение порядка в машинном представлении базового ти­па Т. Значение этого атрибута имеет универсальный ..целый тип.

Примечание. В большинстве машин наибольшее представимое в машине число ти­па Т равно

(T'MACHINE_RADIX) ** (Т MACHINE_EMAX), а наименьшее положительное представимое число в машине равно

(TfaACHINE-RADIX) ** (T'MACHINE_EMIN-1).

  1. Вставки машинных кодов

Машинные коды могут быть включены в программу с помощью вызова процедуры, последовательность операторов которой состоит из операторов кода.

оператор—кода : : = обозначение_типа агрегат_записи;

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

Каждая машинная команда записывается как агрегат именуемого типа, - агрегат определяет эту команду. Базовый тип обозначения типа в операторе кода должен быть описан в предопределенном пакете MACEIINE_CODE; этот пакет должен упоминаться в спецификаторе контекста, применяемом к компилируемому модулю, в который входит оператор кода. Реализация не обязана обеспечивать такой пакет.

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

Реализация может определить машинно-зависимые прагмы, указываю­щие соглашения об использовании регистров и вызовов. Такие соглашения и прагмы должны быть описаны в руководстве по реализации в соответст­вии с обязательным приложением 4.

Пример:

М: МАСКА;

procedure УСТАНОВИТЬ_МАСКУ;

pragma INLINE (УСТАНОВИТЬ_МАСКУ);

procedure УСТАНОВИТЬ_МАСКУ is

use MACHINE_CODE;

begin

ФОРМАТ_СИ' (КОД => SSM, Б = > М'БАЗОВЫЙ_РЕГ, CM => М'СМЕЩ);

- - М'Б АЗОВЫЙ _РЕГ и М'СМЕЩ - это заданные реализацией предопределенные - - атрибуты!

end;

  1. Связь с другими языками

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

pragma INTERFACE (имя_языка, имя_подпрограммы);

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

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

Пример:

package БИБЛ_ФОРТ is

function SQRT (X: FLOAT) return FLOAT;

function EXP (X: FLOAT) return FLOAT;

private

pragma INTERFACE (ФОРТРАН, SQRT);

pragma INTERFACE (ФОРТРАН, EXP);

end БИБЛ_ФОРТ;

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

Прагма INTERFACE не определена для настраиваемых подпрограмм.

  1. Неконтролируемое программирование

Для неконтролируемого освобождения памяти и для неконтролируемо­го преобразования типов используются предопределенные настраива­емые библиотечные подпрограммы: UNCHECKED—DEALLOCATION и UNCHECKED-CONVERSION.

generic

type OBJECT is limited private;

type NAME is access OBJECT;

procedure UNCHECKED _DEALLOCATION (X: in out NAME);

generic

type SOURCE is limited private;

type TARGET is limited private;

function UNCHECKED-CONVERSION (S: SOURCE) return TARGET;

  1. Неконтролируемое освобождение памяти

В результате вызова процедуры, полученной конкретизацией настраи­ваемой процедуры UNCHECKED-DEALLOCATION, производится неконт­ролируемое освобождение памяти, занимаемой объектом, указанным зна­чением ссылочного типа. Например:

procedure СВОБОДНО is new UNCHECKED DEALLOCATION

(имя _типа_объекта, имя ^ссылочного _типа);

Такая процедура СВОБОДНО дает следующий результат:

  1. после выполнения СВОБОДНО (X) значением X является null;

  2. если X уже равно null, то СВОБОДНО (X) не имеет другого резуль­тата;

  3. если X не равно null, то СВОБОДНО (X) обозначает, что указанный значением X объект не требуется, и поэтому занимаемая им память может использоваться для других целей.

Если X и Y указывают на один и тот же объект, тсГ после вызова СВОБОДНО (X) доступ к этому объекту (или попытка доступа к нему) че­рез Y ошибочен; язык не определяет, что происходит в результате такого до­ступа.

Примечание. Согласно правилам видимости настраиваемая процедура UNCHECKED -DEALLOCATION не видима в компилируемом модуле, если только ее имя не указано в спецификаторе совместности этого компилируемого модуля.

Если X указывает на объект задачного типа, то вызов СВОБОДНО (X) никак не влияет на задачу, указанную значением этого объекта. Это же относится и к любому подкомпоненту задачного типа объекта X.

  1. Н е к о н т р о л и р у е м о е преобразование типов Неконтролируемое преобразование типа можно осуществить вызовом функции, полученной конкретизацией настраиваемой функции UNCHECKED-CONVERSION.

Неконтролируемое преобразование типа состоит в возврате значения параметра в качестве значения целевого типа, т. е. поразрядное изображе­ние, определяющее исходное значение, возвращается неизменным, как по­разрядное изображение значения целевого типа. Реализация может нало­жить ограничения на неконтролируемое преобразование типа, например, ограничения, зависящие от предполагаемых размеров объектов исходного и целевого типов. Такие ограничения должны быть отражены в руководст­ве по реализации в соответствии с обязательным приложением 4.

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

Примечание. Согласно правилам видимости настраиваемая функция UNCHECKED-CONVERSION не видима в компилируемом модуле, если она ие упомя­нута в спецификаторе совместности этого компилируемого модуля.

14. ВВОД-ВЫВОД

Ввод-вывод в языке обеспечивается предопределенными пакетами. На­страиваемые пакеты SEQUENTIAL-IO и D1RECT-IO определяют операции ввода-вывода, которые применимы для файлов с элементами данного типа. В пакете ТЕХТ_Ю даны дополнительные операции ввода-вывода текстов. В пакете IO-EXCEPTIONS определены исключения, необходимые для трех указанных пакетов. Наконец, пакет LOW_LEVEL_IO позволяет осуществ­лять непосредственное управление периферийными устройствами.

  1. Внешние файлы и файловые объекты

Значения, вводимые из внешнего для программы окружения или выво­димые в это окружение, размещаются во внешних файлах. Внешним фай­лом может быть нечто внешнее по отношению к программе, которая может произвести читаемое значение или получить записываемое. Внешний файл идентифицируется строкой (именем). Вторая строка (форма) задает до­полнительные системо-зависимые характеристики, которые могут быть со­поставлены с файлом, например, физическая организация или права досту­па. Соглашения об интерпретации таких строк должны быть приведены в руководстве по реализации в соответствии с обязательным приложением 4.

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

Ввод и вывод для последовательных файлов из элементов некоторого типа определены настраиваемым пакетом SEQUENTIAL_IO. Общая струк­тура этого пакета дана ниже.

with IO-EXCEPTIONS;

generic

type ELEMENT_TYPE is private;

package SEQUENTIAL_IO is

type FILE-TYPE is limited private;

type FILE! MODE is (IN_FILE, OUT-FILE);

procedure OPEN (FILE: in out FILE TYPE;. . .);

procedure READ (FILE: in FILETYPE; ITEM: out ELEMENT-TYPE) ;

procedure WRITE (FILE: in FILE TYPE; ITEM: in ELEMENT-TYPE);