Н. Джехани - Язык Ада (1988) (1160771), страница 17
Текст из файла (страница 17)
Спецификация типа объекта снабжает компилятор информацией о предполагаемом использовании объекта. Строго типизированные языки требуют, чтобы ц На зто свойство строгой типизации обратил внимание профессор давил Грис. Е а типах объекты использовались в соответствии с их типами. Например, битовая модель целого значения не может интерпретироваться как действительное, символьное значение не может интерпретироваться как целое, а имя массива не может интерпретироваться как указатель на начальный адрес памяти, отведенной под массив.
Следовательно, ошибки в программе, возникающие при использовании объекта, которое не согласуется с его типом, могут быть обнаружены во время компиляции. Ограниченные эксперименты показали, что строго типизированные языки ведут к повышению ясности и надежности программ [ОАХ77). Нарушение строгой типизации посредством спеииЯикаиии представления затрудняет переносимость программ, так как представление объектов может быть различным в различных реализациях.
Язык Ада — строго типизированный язык. Однако его механизм типизации может быть «проломлен» (т. е. обойден) посредством специальных механизмов, предусмотренных в языка Программы, которые используют эти механизмы, считаются непроверенными программами, так как потенциальные ошибки, возникающие при «проломе» (нарушении), долго не могут быть обнаружены. Нарушение строгой типизации может понадобиться лишь в крайних случаях (обычно в машинно-зависимых системах программирования) и должно использоваться с большой осторожностью.
2.2. ПодтипБ1 [3.3~ Предположим, что переменная С()К- Г1.ООК используется для указания номера этажа в программе для управления лифтом в восьмиэтажном здании. С1)К Н.ООК можно определить как переменную типа 1ХТЕОЕК, но в этом случае ошибочные присваивания ей значений, не входящих в диапазон от ! до 8, автоматически не обнаруживаются. Было бы желательно ограничить значение С()К Н.ООК между 1 и 8 так, чтобы попытки присвоить ей значения, не принадлежащие этому диапазону, автоматически помечались бы как ошибки. Для определения таких ограничений используется механизм подтипов. Множество значений типа Т может быть ограничено при помощи связанного с ним ограничения.
Множество операций, исключая операцию присваивания, не затрагивается. Говорят, что новое множество значений плюс старое множество операций задают подтип; Т есть его базовый тип. Описание подтипа не вводит нового типа. Любой тип Т является подтипом самого себя. Подтип определяют как звЫуре идентификатор 1з указание подтипа; где указание подтипа есть имя типа или подтнпа, за которым следует факультативное ограничение. Ограничения бывают четырех видов: диапазон, индекс, точность и дискриминанпь Например, ограничение диапазона гапйе 1..
8 используется при описании подтипа БТОК1ЕБ звЫуре БТОК1ЕБ )з 1ХТЕОЕК гапйе 1..8; для того чтобы ограничить допустимые значения всех объектов подтипа БТОК1ЕБ целыми значениями между 1 и 8. Некоторые характеристики типов и подтипов, такие как специальные значения и операции, доступны пользователю и называются атрибутами типов и под- Глввв 2 типов. Базовый тип любого подтипа (или типа) Т определяется атрибутом Т'ВАБЕ.
Этот атрибут можно использовать только для формирования других атрибутов, например Т'ВАБЕ'Р1КБТ, который обозначает наименьший элемент базового типа Т. (Список всех предопределенных атрибутов дается в приложении А руководства по языку Ада.) При описании подтипа пользователь задает дополнительную информацию, что повышает удобочитаемость программ и позволяет компилятору гарантировать, что все значения, присвоенные переменным подтнпа, удовлетворяют связанным с ним ограничениям.
Оптимизирующий компилятор может использовать ограничения множества значений, определенных при помощи подтипа для того, чтобы оптимизировать занимаемую память, требуемую для объектов подтипа (по сравнению с памятью, требуемой для объектов базового типа или подтипа). 2.2.1. Примеры подтипов %ЕЕКкзАУ Ь ОАУ гапйе МОХ..РК1; тип ОАУ определен ранее отметим ограничение диапазона %ЕЕКЕХО 18 ОАУ гапйе БАТ..Б(ЗХ; ВУРРЕК Б1УЕ Ь 1ХТЕОЕК гапйе О..МАХ; ОКАкзЕБ Ь ЧЕСТОК (1..50); ЧЕСТОК есть неограниченный индексируемый тип; ограничение индекса 1..50 дано в описании подтипа МАЬЕ Ь РЕКБОХ(БЕХ = ) М); РЕКБОХ есть именуемый тип с дискриминантом; дискриминант БЕХ ограничивается, чтобы иметь значение М (тип записи с дискриминантами будет обсуждаться позднее в этой главе) япЫуре ивЫУРе ацЫуре заЬСуре заЫУРе 2.3.
Производные типы [3.41 " Дкннкя стратегия в общем случае не подходит для обработки зикчений с различными единицами измерения или для автоматического преобразования знвчении с одинаковыми единицами измерения [бЕН77, ОЕН82б, ГзЕН82в]. Предположим, что две переменные Р и Б представляют стоимость топлива и скорость поезда. Р и Б могут быть описаны как некоторый действительный тип, скажем Н.ОАТ, но тогда случайные ошибки, такие как присваивание переменной Р значения переменной Б или наоборот, нельзя автоматически обнаружить.
Было бы желательно определить Р и Б так, чтобы они имели типы С1ЖКЕХСУ и БРЕЕкз, которые имеют такое же множество значений и такое же множество операций, как Н.ОАТ, но будут отличаться друг от друга и от Н.ОАТ. Ошибочное использование переменных типа С1ЖКЕХСУ для переменных типа БРЕЕР, Н.ОАТ и др. должно обнаруживаться автоматически. Такое удобство обеспечивается при помощи производных лгиловп в языке Ада. Производный тип является новым н отличным типом, производным от существующего типа, называемого родшпельским типом.
Производный тип копирует значения и операции из значений и операций своего родительского типа. Произ- вз Е о типах водные типы объявляются как гуре ХЕ% ТУРЕ Ь печу ОЬО ТУРЕ ]ограничение]; Ограничение, указанное в описании производного типа ХЕ% ТУРЕ, должно быть совместимо с любыми ограничениями, наложенными родительским типом ОЬР-ТУРЕ. Как и в случае подтипов, ограничения могут быть четырех родов — диапазона, индекса, точности и дискриминанта. Возможно преобразование между производным типом и его родительским типом. Производный тип использует ту же самую нотацию для литералов и агрегатов, как и родительский тип.
Такие литералы и агрегаты называют совмещенными, так как они обозначают значения для более чем одного типа. Тип литерала или агрегата должен однозначно определяться из контекста; в противном случае он должен явно задаваться программистом. 2.3.1. Примеры производных типов гуре РК1МАКУ СОЬОК Ь печу СО1.ОК„ — новое ограничение не накладывается гуре АОЕ Ь пете 1ХТЕОЕК гапке 0..150; — наложены ограничения диапазона гуре САКР Ь печу ЫХЕ (1..80); — наложены ограничения индекса 2.4.
Эквивалентность типов Эквивалентность типов можно разбить на два широких класса — именную и структурную [%ЕЬ77]. Когда эквивалентны два типа в языке Ада? Язык Ада использует концепцию именной эквивалентностио для определения того, когда два типа эквивалентны. Два объекта имеют эквивалентные типы тогда и только тогда, когда они описаны с помощью одного и того же идентификатора типа.
Каждое описание типа, такое как аггау (1 .. 10) оу 1ХТЕОЕК задает новый тип, называемый анонимным типом, который отличается от всех других типов. Например, А и В, описанные в различных описаниях единичных объектов: А: аггау(1..10) о1' 1ХТЕОЕК; В: аггау(1..10) о1' 1ХТЕОЕК; не принадлежат одному типу, потому что каждое описание создает новое анонимное определение индексируемого типа. Даже если бы А и В были описаны вместе в одном групповом описании объектов А, В:аггау(1..10) о1 1ХТЕОЕК; "Именная эквивалентность концептуально проше и легче реализуется, чем структурная эквивалентность. При структурной эквивалентности два типа эквивалентны тогда и только тогда, когда их компоненты имеют одинаковые типы независимо от имен этих компонент.
Сушествуют различные варианты этой схемы. вг Глава 2 они были бы различных типов, так как групповое описание объектов эквивалент- но серии единичных описаний объектов (3.3.!]. В качестве другого примера рас- смотрим идентификатор типа АККАУ10, описанный как (уре АККАг'10 1з аггау (1..10) оу 1ХТЕСЕК; После описания Е, Е: АККАУ10; С: АККАз"10; Е, Е и С имеют одинаковый тип, так как все они описаны с использованием одинакового идентификатора типа. 2.5. Преобразование типа [4.6] Т(Е) Преобразование типа разрешено только для: Е может быть выражением любого числового типа. Преобразование вещественных к целым осуществляется с помощью округления до ближайшего целого Числовых типов Т и тип Е должны быть производными один от другого прямо или косвенно, нли должен существовать третий тип, от которого они производны прямо или косвенно.
Это преобразование может приводить к изменению представления [13.б[ Производных типов Индексируемых типов Т и Е должны иметь одинаковую размерность, одинаковые типы индексов и компонент. В случае если типы индексов отличаются, они должны быть преобразуемы друг в друга.
Если типы компонент есть ссылочные типы или именуемые типы, то они должны быть оба либо ограниченны, либо неограниченны. Если Т обозначает ограниченный тип и Е имеет точно такое же число элементов, как и Т, то границы результата совпадают с границами, указанными типом Т. Если Т обозначает неограниченный тип, то границы результата являются такими же, как у Е. Всякий раз, когда возможно преобразование типа, обратное преобразование так- же возможно. Выражение Е можно преобразовать в другой тип нли подтип с помощью квалификации его именем типа или подтипа Т; это записывается как Е о тилля 2.5.1. Неявные преобразования Язык Ада не допускает неявных преобразований".
Некоторые специалисты в области информатики считают, что неявные преобразования никогда не должны разрешаться, даже если они имеют математический смысл, потому что преобразования делают программы более трудными для понимания (ыз7б). Переход от подтипа к его базовому типу или наоборот (в предположении, что значение принадлежит подтипу) не считается преобразованием типа, потому что описание подтипа реально не вводит нового типа. Объекты подтипа Б действительно имеют тип Т, базовый тип для Б, но значения, которые могут быть присвоены объектам, ограничены множеством значений, указанных в описании Б. 2.б.
Квалифицированные выражения Тип выражения определяется исходя из типов его операндов и типов значений, возвращаемых операторами. Квали(рицированное выражение используется для того, чтобы явно устанавливать тип выражения или агрегата. Квалификация выражений или агрегатов с типами необходима в случаях, когда тип нельзя определить из контекста. Например, рассмотрим два литерала А и В, которые принадлежат к двум различным перечислимым типам Е и Е Тогда выражение А<В является двусмысленным, потому что нельзя определить из контекста, принадлежат ли А и В к Е или Е Значение такого выражения может быть различным в зависимости от типов А и В.