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).

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

RЕАL(2 * J)    -- значение преобразуется к плавающему типу INТЕGЕR(1.6)   -- значение равно 2 INТЕGЕR(-0.4)               -- значение равно 0

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

type A_FORM is new BFORM;X : AFORM; Y : BPORM;X := A_FORM(Y); Y := B_FORM(X); -- обратное преобразование

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

type SEQUENCE is array (INTEGER range <>) of INTEGER: subtype DOZEN is SEQUENCE(1 .. 12); LEDGER : array(1 .. 100) of INTEGER;SEQUENCE(LEDGER)             -- с границами как у LEDGER SEQUENCE(LEDGER(31 .. 42))   -- с границами 31—42 DOZEN(LEDGER(31 .. 42))      -- с границами как у DOZEN

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

Х : INTEGER := 2; X + 1 + 2          -- неявное преобразование каждого целого литерала 1 + 2 + X          -- неявное преобразование каждого целого литерала X + (1 + 2)        -- неявное преобразование каждого целого литерала2 = (1 + 1)                                 -- тип - универсальный-целый                                            -- неявных преобразований нет                    A'LENGTH = B'LENGTH                         -- то же, что и выше                             С : constant := 3 + 2    -- то же, что и выше                             X = 3 and 1 = 2          -- неявное преобразование 3, но не 1 и 2         

Ссылки: атрибут 4.1.4, базовый тип 3.3, вещественный тип 3.5.6, вид 6.1, возбуждение исключений 11, выражение 4.4, именованное число 3.2, имя 4.1, индекс 3.6, индексируемый тип 3.6, исключение CONSTRAINED-ERROR 11.1, компонента 3.3, неограниченный индексируемый тип 3.6, обозначение типа 3.3.2, ограниченный индексируемый подтип 3.6, оператор 5, переменная 3.2.1, плавающий тип 3.5.7, подтип 3.3, подтип индекса 3.6, представление 13.1, принадлежать подтипу 3.3, производный тип 3.4, пустой массив 3.6.1, размерность 3.6, сопоставленная компонента 4.5.2, тип 3.3, тип индекса 3.6, универсальный вещественный тип 4.5.6, универсальный целый тип 3.5.4, фактический параметр 6.4.1, целый тип 3.5.4, числовой литерал 2.4, числовой тип 3.5.