Rationale for Ada 2005: Introduction
RUSTOPBACKNEXT
ENG |
3.5 Exceptions, numerics, generics etc
@ As well as the major features discussed above there are also a number of improvements in various other areas. @ There are two small changes concerning exceptions. One is that we can give a message with a raise statement, thus
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale for Ada 2005: Introduction
ENGRUSTOPBACKNEXT3.5 Исключения, численные данные, настраиваемые средства и т.д.
@ Наряду с основными особенностями, обсуждаемыми выше, есть ряд усовершенствований в некоторых других областях.
@ Есть два небольших изменения относительно исключений. Первое, это то, что мы теперь можем выдать некое сообщение вместе с raise оператором:
|
@ Это гораздо более удобно чем писать на Аде 95:
|
@ Другое изменение касается обнаружения нулевого вхождения исключения, которое могло бы быть полезным в пакете анализа логики исключений. Проблема состоит в том, что вхождение исключений имеет ограниченный частный тип и таким образом мы не можем сравнить его с Null_Occurrence, чтобы определить, равны ли они. На Аде 95 применение функции Exception_Identity к нулевому вхождению бесполезно и возбуждает исключение Constraint_Error. Это было изменено в Аде 2005, чтобы возвратить Null_Id так, чтобы мы могли теперь написать:
|
@ В Аде 95 были введены модульные типы, которые являются целыми числами без знака. Однако, практика показала, что очень трудно заставить сотрудничать знаковые и беззнаковые числа. Этот тривиальный вопрос в таких языках как C в Аде с её тотальным контролем преобразования типов оказалася труднопреодолимым. Основная проблема - необходимость преобразования типов, который случается когда отрицательное число приводится к числу без знака. Пусть мы хотим добавить некоторое смещение к значению адреса без знака, тогда мы могли бы написать:
|
@ Мы не можем просто добавить Offset к Address, потому что они имеют различные типы. При преобразовании Offset в тип Addres мы можем получить Constraint_Error. Теперь на Аде 2005 мы можем использовать новый функциональный атрибут S'Mod, который относится к любому модульному подтипу S и преобразовывает универсальное целочисленное значение в модульный тип, используя соответствующую математическую ультрасовременную операцию. Таким образом, мы можем теперь написать:
|
@ Другой новый атрибут - Machine_Rounding. Он разрешает высокоэффективное преобразование чисел с плавающей запятой в целочисленный тип, когда точное округление не имеет значения.
@ Третья числовая проблема связана с типами чисел с фиксированной точкой. Это была обычная практика для программ на Аде 83, чтобы определить их собственные операции умножения и деления, возможно получить арифметическое переполнение. На Аде 95 эти возможности вступили в конфликт с правилами, которые ввели универсальные установленные операции и привели к двусмысленностям. Без того, чтобы сообщать подробности эта проблема была решена на Аде 2005 так, чтобы определяемые пользователем операции могли бы теперь использоваться.
@ У Ады 2005 есть несколько новых прагм. Первая:
|
@ где Identifier - идентификатор проверки, такой как Range_Check. Общее представление должно гарантировать, что проверки выполнены в декларативной области независимо от использования соответствующей прагмы Supress. Таким образом, у нас мог бы быть тип My_Int, который ведет себя как saturated тип. Текст:
|
@ гарантирует, что код всегда работает как предназначено, даже если проверки подавлены в программе в целом. Случайно параметр On прагмы Supress, который никогда не использовался был помещён в Приложение J.
@ Большинство реализаций ada поддерживают прагму Assert, она теперь включена в стандарт Ады 2005. Теперь мы можем написать:
|
@ Первый параметр прагмы - булевское выражение, второй дополнительный параметр - строка. Если при выполнении прагмы первый параметр принимает значение - False тогда некое действие может быть предпринято. Этим действием управляет другая прагма Assertion_Policy, которая может переключить механизм утверждения в положение ВКЛ. или ВЫКЛ. одним из выражений:
|
@ Если политика установлена Check, тогда исключение Assertion_Error возбуждается с сообщением, если любой. Это исключение объявлено в предопределенной пакете Ada.Assertions. Также есть некоторые другие средства.
@ Прагма No_Return также связана с исключениями. Она может быть применена к процедуре (не к функции) и указывает, что процедура никогда не возвращает управление обычным образом, только размножая исключение. Таким образом, мы могли бы написать:
|
@ И теперь всякий раз, когда мы вызываем процедуру Fatal_Error, компилятор уверен, что управление не будет возвращено, и может выполнить соответствующую оптимизацию и/или повысить адекватность сообщений при исключениях.
@ Отметим, что эта прагма относится к предопределенной процедуре Ada.Exceptions.Raise_Exception.
@ Другая новая прагма - Preelaborable_Initialization. Она используется с частными типами и указывает, что у полного типа будет preelaborable инициализация. Большинство примеров можно найти в предопределенных пакетах, например в таком как
|
@ в Ada.Finalization.
@ Наконец, есть прагма Unchecked_Union. Она полезна для интерфейса с программами, написанным на C, которые используют понятие объединений. Объединения в C соответствуют вариантным записям Ады, но без сохранения дискриминантов, который находится полностью в уме программиста C. Эта прагма дает возможность объединению C отображаться в тип вариантной записи Ады, опуская память для дискриминанта. Если программа C имеет следующий код:
|
@ тогда соответствующий код на Adе будет выглядеть как:
|
@ Одна проблема с прагмами (и атрибутами) состоит в том, что много реализаций добавили свои специфические прагмы (поскольку это действительно разрешено стандартом). Однако, это может препятствовать переносимости программ из одной реализации в другую. Для преодоления этой проблемы имеется идентификатор Restrictions, и теперь мы можем написать:
|
@ Заметим, что одна из целей Ады 2005 стандартизировать все атрибуты и прагмы насколько возможно.
@ Внимательный читатель мог бы обратить внимание на парадокс, что у GNAT есть (определенный реализацией) идентификатор ограничений No_Implementation_Restrictions.
@ Другой новый идентификатор ограничений предотвращает нас от небрежного использования особенностей внесённых в Приложение J следующим образом:
|
@ Так же мы можем использовать идентификатор ограничений No_Dependence, чтобы заявить, что программа не зависит от данного библиотечного модуля. Таким образом мы могли бы написать:
|
@ Отметим, что упомянутый модуль мог бы быть предопределенным библиотечным модулем как в вышеупомянутом примере, но этот идентификатор может также использоваться с любым другим библиотечным модулем.
@ Последняя новая особенность касается формальных параметров настраиваемых пакетов. Ада 95 ввела возможность иметь формальные пакеты в виде параметров универсальных модулей. Это значительно уменьшало потребность в длинных универсальных списках параметров, так как формальный пакет формировал их.
@ Иногда для настраиваемого модуля необходимо иметь два (или больше) формальных пакета. При этом, часто необходимо чтобы некоторые из фактических параметров одного формального пакета должны быть идентичны таковым из другого. Чтобы разрешить это имеется две формы настраиваемых параметров. Первая:
|
@ и затем пакет Gen может быть проиллюстрирован с любым пакетом, который является реализацией Q. Другим способом это делается так:
|
@ и затем пакет Gen может только быть проиллюстрирован с пакетом, который является реализацией S с данными фактическими параметрами P1, P2 и т.д.
@ Эти механизмы часто используются вместе:
|
@ Это гарантирует, что у реализации S есть тот же самый фактический параметр (принимал только один в этом примере) как параметр F1 Q, используемого в реализации Q, чтобы создать фактический пакет, соответствующий P.
@ Есть пример этого в одном из пакетов для векторов и матриц в ISO/IEC 13813, который теперь включен в Аду 2005 (см. Раздел 3.6). У настраиваемого пакета для сложных массивов есть два параметра пакета. Первый - соответствующий пакет для реальных массивов, другой - пакет Generic_Complex_Types от существующего приложения Численных данных. У обоих из этих пакетов есть тип с плавающей точкой как единственный формальный параметр, и важно, что обе реализации используют один и тот же тип с плавающей точкой (оба с плавающей точкой, а не один с плавающей точкой, а другой Long_Float) иначе, произойдет нечто ужасное. Это гарантируется написанием (здесь мы опускаем некоторые подробности):
|
@ Это прекрасно работает в простых случаях (читатель может задаться вопросом, прост ли этот пример или нет), но в более сложных ситуациях это - большая головная боль. Неприятность состоит в том, что мы должны дать все параметры для формального пакета или ни одного вообще в Аде 95.
@ Ада 2005 разрешает быть определенными только части параметров, а любой не определенный параметр может быть обозначен блоком <>. Таким образом, мы можем написать любой из следующих вариантов:
|
@ Отметим, что существующая форма (<>) является сокращением для (others => <>). Во всех остальных случаях применение формы <> разрешено только с именоваными агрегатами.
@ Примеры использования этого нового средства будут даны в более поздней публикации.
2010-10-24 00:26:52
. .