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

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

Примечание. Для плавающего типа числа 15.0, 3.0 и 5.0 всегда являются модель­ными числами. Следовательно, X/Y, где X равно 15.0, a Y равно 3.0, согласно приве­денным выше правилам вырабатывает в результате точно 5.0. В общем случае деление не вырабатывает в результате модельные числа и, следовательно, нельзя рассчитывать, что выполнено равенство (1.0/Х) * X = 1.0.

4.6. Преобразование типа

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

преобразование_ типа : : = обозначение_типа (выражение)

Целевой тип преобразования типа — это базовый тип обозначения типа. Тип операнда преобразования типа должен быть определимым независимо от контекста (в частности, независимо от целевого типа). Более того, недо­пустимо, чтобы операнд преобразования типа был литералом null, генерато­ром, агрегатом или строковым литералом; задание в качестве операнда преобразования типа выражения, заключенного в скобки, допускается толь­ко если само выражение является допустимым.

Преобразование к подтипу состоит в преобразовании к целевому типу с последующей проверкой принадлежности результата этому подтипу. До­пускается преобразование операнда заданного типа к тому же самому типу.

Другие явные преобразования типов допустимы в следующих трех слу­чаях.

  1. Числовые типы.

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

  1. Производные типы.

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

  1. Индексируемые типы.

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

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

При вычислении преобразований числовых и производных типов воз­буждается исключение CONSTRAINT-ERROR, если результат преобразова­ния не удовлетворяет заданным в обозначении типа ограничениям.

При преобразовании индексируемых типов проверяется, что любое ог­раничение подтипа компонента одинаково для индексируемого типа операн­да и для целевого индексируемого типа. Если обозначение типа задает неог­раниченный индексируемый тип и если операнд не является пустым масси­вом, то для каждой позиции индекса проверяется принадлежность границ результата соответствующему подтипу индекса целевого типа. Если обозна­чение типа задает ограниченный индексируемый подтип, то для каждого компонента операнда проверяется наличие соответствующего компонента целевого подтипа, и наоборот. Если хотя бы одна из этих проверок дает от­рицательный результат, возбуждается исключение CONSTRAINT—ERROR.

Если допустимо преобразование одного типа в другой, то также допус­тимым является и обратное преобразование. Это обратное преобразование используется тогда, когда фактический параметр вида in out или out имеет форму преобразования типа имени (переменной), как это поясняется в разд. 6.4.1.

Единственной допустимой формой неявного преобразования типа яв­ляется преобразование значения универсального _целого или универсаль­ного ^вещественного типов в значение другого числового типа. Неявное преобразование операнда универсального_целого типа в другой целый тип или операнда универсального-вещественного типа в другой вещественный тип возможно только для операнда, являющегося либо числовым литера­лом, либо именованным числом, либо атрибутом; в этом разделе такой операнд называется преобразуемым универсальным операндом. Неявное преобразование преобразуемого универсального операнда применимо тогда и только тогда, когда самый вложенный полный контекст (см. 8.7) опреде­ляет единственный (числовой) целеьой тип для этого неявного преобразо­вания, и, кроме этого преобразования, не существует иной, предписанной языком, правильной интерпретации этого контекста.

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

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

Для индексируемых типов в языке допускается неявное преобразование подти­пов (см. 5.2.1). Последствием явного преобразования типа может быть изменение представления (в частности, см. 13.6). Явные преобразования используются также для фактических параметров (см. 6.4).

Примеры преобразования числовых типов:

ВЕЩЕСТВ (2 * К) -- значение преобразуется к плавающему типу

INTEGER (1.6) - - значение равно 2

INTEGER (-0.4) - - значение равно 0

Примеры преобразования производных типов:

type А. ФОРМ is new В_ФОРМ;

Х:А_ФОРМ;

Y: ВФОРМ;

X: = А_ФОРМ (Y);

Y: = В__ФОРМ (X); - - обратное преобразование

Примеры преобразований индексируемых типов:

type ПОСЛЕДОВАТЕЛЬНОСТЬ is array (INTEGER range < >) of INTEGER;

subtype ДЮЖИНА is ПОСЛЕДОВАТЕЛЬНОСТЬ (1.12);

ЖУРНАЛ: array (1. .100) of INTEGER;

ПОСЛЕДОВАТЕЛЬНОСТЬ (ЖУРНАЛ) - - с границами как у ЖУРНАЛ

ПОСЛЕДОВАТЕЛЬНОСТЬ (ЖУРНАЛ (31. .42)) --с границами 31-42

ДЮЖИНА (ЖУРНАЛ (31. .42)) - - с границами, как у ДЮЖИНА

Примеры неявных преобразований:

X: INTEGER : = 2;

X + 1 + 2 - - неявное преобразование каждого целого литерала

  1. + 2 + X - - неявное преобразование каждого целого литерала

X + (1 + 2) - - неявное преобразование каждого целого литерала

  1. = (1 + 1) - - тип - универсальный _целый, неявных преобразований нет

A'LENGTH = B'LENGTH - - то же, что и выше

С: constant : = 3 + 2; - - то же, что и выше

X = 3 and 1 = 2-- неявное преобразование 3, но не 1 и 2

  1. Квалифицированные выражения

Квалифицированное выражение используется для явного указания типа и, возможно, подтипа операнда, заданного выражением или агрегатом.

квалифицированное—выражение : : = обозначение—типа' (выражение) | обозначение—типа агрегат

Типом операнда должен быть базовый тип обозначения типа. Значение квалифицированного выражения — это значение операнда. Вычисление ква­лифицированного выражения выдает операнд и проверяет, принадлежит ли его значение подтипу, заданному в обозначении типа. При отрицательном ре­зультате проверки возбуждается исключение CONSTRAINT-ERROR.

Примеры:

type МАСКА is (FIX, DEC, EXP, SIGNIF);

type КОП is (FIX, CLA. DEC, TNZ, SUB);

PRINT (МАСКА' (DEC));--DEC типа МАСКА

PRINT (КОП' (DEC)) ; - - DEC типа КОП

for К in КОП' (FIX) .. КОП' (DEC) loop .. .

  • - квалификация необходима либо для FIX, либо для DEC

for К in КОП range FIX.. DEC loop .. .

  • - квалификация не нужна

for К in КОП' (FIX) . . DEC loop . . .

  • - квалификация для DEC не нужна

ДЮЖИНА' (11315 |7 => 2, others => 0) - -см. 4.6.

Примечание. Когда тип литерала перечисления или агрегата неизвестен из контекс­та, квалифицированное выражение может быть использовано для явного установления типа. Например, совмещенный литерал перечисления должен быть квалифицирован в следующих случаях: при использовании его в качестве параметра в вызове совмещен­ной подпрограммы, которая не может быть идентифицирована на основе типов осталь­ных параметров и типа результата; в отношении, в котором оба операнда - совмещен­ные литералы перечисления; в массиве или диапазоне параметра цикла, в которых обе границы - совмещенные литералы перечисления. Явная квалификация используется также для определения совмещенной функции без параметров или для ограничения значения данным подтипом.

  1. Генераторы

Вычисление генератора создает объект и вырабатывает ссылочное значе­ние, которое указывает этот объект.

генератор : : = new указание_подтипа

I new квалифицированное_выражение

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

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

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

При вычислении генератора сначала производится предвыполнение ука­зания подтипа или вычисление квалифицированного выражения. Затем соз­дается новый объект. Далее осуществляется инициализация как для описан­ного объекта (см. 3.2.1) : явно — для квалифицированного выражения, не­явно — для указания подтипа. Наконец, возвращается ссылочное значение, указывающее на созданный объект.

Реализация должна гарантировать сохранение объекта, созданного при вычислении генератора, до тех пор, пока сам объект или хотя бы один из его подкомпонентов доступны непосредственно или косвенно, т. е, пока он может быть обозначен некоторым именем. Кроме того, если объект или один из его подкомпонентов принадлежат заданному типу, он считается до­ступным, пока не завершена эта задача. Реализация может (но не обязана) освобождать память, занятую объектом, созданным генератором, как толь­ко этот объект становится недоступным.

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

  1. Общий объем памяти, доступный для набора объектов ссылочного типа, может быть установлен с помощью спецификатора длины (см. 13.2).

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

pragma CONTROLLED (простое_имя_ссылочного_типа);

Эта прагма для данного ссылочного типа допустима в тех же местах, что и спецификатор представления этого типа (см. 13.1).

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

При исчерпании памяти генератором возбуждается исключение STORAGE-ERROR. Заметим также, что исключение CONSTRAINT-ERROR может быть возбуждено при вычислении квалифицированного выражения, во время предвыполнения указания подтипа или при инициализации.

Примеры (ссылочных типов, описанных в разд. 3.8):

new ЯЧЕЙКА' (0, null, null) - - явная инициализация

new ЯЧЕЙКА' (ЗНАЧЕНИЕ => 0, СЛЕД => null, ПРЕД => null)

• - явная инициализация

new ЯЧЕЙКА - - нет инициализации

new МАТРИЦА' (1. .10, 1. .20) - - даны только границы