Для результата операции отношения между двумя вещественными операндами рассмотрим модельный интервал (подтипа операнда), определенный для каждого такого операнда; результат может быть любым значением, полученным при применении математического сравнения к значениям, произвольно выбранным в соответствующих модельных интервалах операндов. Если один или оба модельных интервала операндов не определены (и если при вычислении операндов не было возбуждено исключение), то в качестве результата сравнения допустимо любое возможное значение (т. е. либо 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, генератором, агрегатом или строковым литералом; задание в качестве операнда преобразования типа выражения, заключенного в скобки, допускается только если само выражение является допустимым.
Преобразование к подтипу состоит в преобразовании к целевому типу с последующей проверкой принадлежности результата этому подтипу. Допускается преобразование операнда заданного типа к тому же самому типу.
Другие явные преобразования типов допустимы в следующих трех случаях.
Числовые типы.
Значение операнда любого числового типа может быть преобразовано в значение целевого типа, который должен быть также числовым. Для преобразования вещественных типов точность результата лежит в пределах точности заданного подтипа (см. 4.5.7).’ Преобразование значения вещественного типа в значение целого типа состоит в его округлении до ближайшего целого; для вещественного операнда, равноотстоящего от двух целых (с точностью этого вещественного подтипа), округление может быть произведено как в ту, так и в другую сторону.
Производные типы.
Преобразованйе. допустимо, если либо целевой тип, либо тип операнда являются производными один от другого, непосредственно или косвенно, или если существует третий тип, от которого производными являются оба и тип операнда, и целевой тип, непосредственно или косвенно.
Индексируемые типы.
Преобразование допустимо, если тип операнда и целевой тип — индексируемые типы, которые удовлетворяют следующим условиям: оба типа должны иметь одну и ту же размерность; в каждой позиции индекса типы индексов должны быть либо одинаковыми, либо взаимопреобразуемыми; типы компонентов должны быть одинаковыми; наконец, если тип компонента — тип с дискриминантами или ссылочный тип, то подтипы компонентов должны быть оба либо ограниченными, либо неограниченными.
Если обозначение типа задает неограниченный индексируемый тип, то для каждой позиции индекса границы результата преобразования определены преобразованием границ операнда в значения соответствующего типа индекса целевого типа. Если обозначение типа задает ограниченный индексируемый тип, то границы результата совпадают с границами, указанными в обозначении типа. В обоих случаях значение каждого компонента результата определяется соответствующим компонентом операнда (см. 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 - - неявное преобразование каждого целого литерала
+ 2 + X - - неявное преобразование каждого целого литерала
X + (1 + 2) - - неявное преобразование каждого целого литерала
= (1 + 1) - - тип - универсальный _целый, неявных преобразований нет
A'LENGTH = B'LENGTH - - то же, что и выше
С: constant : = 3 + 2; - - то же, что и выше
X = 3 and 1 = 2-- неявное преобразование 3, но не 1 и 2
Квалифицированные выражения
Квалифицированное выражение используется для явного указания типа и, возможно, подтипа операнда, заданного выражением или агрегатом.
квалифицированное—выражение : : = обозначение—типа' (выражение) | обозначение—типа агрегат
Типом операнда должен быть базовый тип обозначения типа. Значение квалифицированного выражения — это значение операнда. Вычисление квалифицированного выражения выдает операнд и проверяет, принадлежит ли его значение подтипу, заданному в обозначении типа. При отрицательном результате проверки возбуждается исключение 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.
Примечание. Когда тип литерала перечисления или агрегата неизвестен из контекста, квалифицированное выражение может быть использовано для явного установления типа. Например, совмещенный литерал перечисления должен быть квалифицирован в следующих случаях: при использовании его в качестве параметра в вызове совмещенной подпрограммы, которая не может быть идентифицирована на основе типов остальных параметров и типа результата; в отношении, в котором оба операнда - совмещенные литералы перечисления; в массиве или диапазоне параметра цикла, в которых обе границы - совмещенные литералы перечисления. Явная квалификация используется также для определения совмещенной функции без параметров или для ограничения значения данным подтипом.
Генераторы
Вычисление генератора создает объект и вырабатывает ссылочное значение, которое указывает этот объект.
генератор : : = new указание_подтипа
I new квалифицированное_выражение
Тип созданного генератором объекта — это базовый тип обозначения типа, заданного либо в указании подтипа, либо в квалифицированном выражении. Для генератора с квалифицированным выражением это выражение задает начальное значение создаваемого объекта. Тип ссылочного значения, вырабатываемого генератором, должен быть определимым только из контекста, с учетом того, что это значение является ссылкой на указанный в генераторе тип.
Ограничение индекса и ограничение дискриминанта являются единственными допустимыми формами ограничения в указании подтипа генератора. Если в генераторе стоит указание подтипа, и если порождаемый объект имеет индексируемый тип или тип с дискриминантами, которые не содержат выражений по умолчанию, то указание подтипа должно либо обозначать ограниченный подтип, либо содержать явное ограничение индекса или дискриминанта.
Создаваемый объект индексируемого типа или типа с дискриминантами всегда ограничен. Для генератора с указанием Подтипа создаваемый объект ограничен либо этим подтипом, либо значениями дискриминанта по умолчанию. Для генератора с квалифицированным выражением создаваемый объект ограничен границами или дискриминантами начального значения. Для других типов создаваемый объект имеет подтип, определенный указанием подтипа в определении ссылочного типа.
При вычислении генератора сначала производится предвыполнение указания подтипа или вычисление квалифицированного выражения. Затем создается новый объект. Далее осуществляется инициализация как для описанного объекта (см. 3.2.1) : явно — для квалифицированного выражения, неявно — для указания подтипа. Наконец, возвращается ссылочное значение, указывающее на созданный объект.
Реализация должна гарантировать сохранение объекта, созданного при вычислении генератора, до тех пор, пока сам объект или хотя бы один из его подкомпонентов доступны непосредственно или косвенно, т. е, пока он может быть обозначен некоторым именем. Кроме того, если объект или один из его подкомпонентов принадлежат заданному типу, он считается доступным, пока не завершена эта задача. Реализация может (но не обязана) освобождать память, занятую объектом, созданным генератором, как только этот объект становится недоступным.
В случаях, когда требуется более точное управление распределением памяти под указанные значениями ссылочного типа объекты, оно может быть обеспечено следующими средствами.
Общий объем памяти, доступный для набора объектов ссылочного типа, может быть установлен с помощью спецификатора длины (см. 13.2).
Прагма CONTROLLED сообщает реализации, что для объектов, указанных значениями ссылочного типа, автоматическое возвращение памяти производиться не должно, исключая случаи выхода из самого вложенного оператора блока, тела подпрограммы или тела задачи, содержащих описание этого ссылочного типа, или выхода из главной программы.
pragma CONTROLLED (простое_имя_ссылочного_типа);
Эта прагма для данного ссылочного типа допустима в тех же местах, что и спецификатор представления этого типа (см. 13.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) - - даны только границы