Rationale for Ada 2005: Access types
RUSTOPBACKNEXT
ENG |
2. Null exclusion and constant
@ In Ada 95, anonymous access types and named access types have unnecessarily different properties. @ Furthermore anonymous access types only occur as access parameters and access discriminants. @ Anonymous access types in Ada 95 never have null as a value whereas named access types always have null as a value. Suppose we have the following declarations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale for Ada 2005: Access types
@ENGRUSTOPBACKNEXT2. Нулевые исключения и константы
@ В Аде 95 анонимные и именованные ссылочные типы имеют излишне разные свойства.
@ Кроме того, анонимные ссылочные типы разрешены только как ссылочные параметры и ссылочные дискриминанты.
@ Анонимным ссылочным типам в Аде 95 не разрешено иметь пустой указатель в качестве значения, тогда как именованным ссылочным типам это разрешается. Предположим, что мы имеем следующее объявление:
|
@ Здесь T_Ptr назначается пустой указатель по умолчанию. Теперь предположим, что мы имеем процедуру с ссылочным параметром:
|
@ В Аде 95 ссылочный параметр, такой как A никогда не имеет пустой указатель в качестве значения и, таким образом, нет никакой потребности проверять пустой указатель при обращении к A.Component. Проверка обязательно выполняется при вызове процедуры P. При этом, если фактический параметр поцедуры P окажется равным null то возбуждается исключение Constraint_Error. Идея состояла в том, чтобы в пределах P иметь более эффективный код для разыменования и обработки за счет только одной проверки при вызове процедуры. Такой ссылочный параметр мы считаем подтипом, который исключает пустой указатель.
@ Ада 2005 расширяет эту идею относительно ссылочных типов также исключая пустой указатель к именованным ссылочным типам. Таким образом, мы можем написать:
|
@ В этом случае объект типа Ref_NNT не может иметь пустое значение указателя. Поэтому все объекты этого типа должны быть явно проинициализированы - иначе при инициализации пустым указателем по умолчанию возникнет исключение Constraint_Error.
@ Так как свойство запрещающее пустой указатель теперь можно явно назначить для именованных типов, было решено, что для однородности, анонимные ссылочные типы должны следовать тем же самым правилам, когда это возможно. Так, если мы хотим, чтобы ссылочный параметр A исключал пустой указатель в Аде 2005 мы должны указать это следующим образом:
|
@ Это означает, что первоначальная процедура:
|
@ на Аде 2005 ведет себя немного по-другому т.к. A больше не имеет тип, который исключает пустой указатель. Теперь должна выполняться проверка каждый раз при обращении к компоненте записи, потому что пустой указатель теперь - запрещённое значение для A. Так в Аде 2005 вызов процедуры P с нулевым параметром приводит к исключению Constraint_Error возникающему в пределах P только когда мы пытаемся сделать разыменовывание, тогда как на Аде 95 оно всегда возбуждается в точке вызова.
@ Это ранее упоминавшаяся несовместимость особого вида при которой программа является синтаксически правильной и на Аде 95 и на Аде 2005, но при выполнении она ведет себя по-разному, т.к. исключение Constraint_Error возбуждается в разных местах. Но на практике возбуждение исключения Constraint_Error означает явную (несовместимую с жизнью) ошибку и различия (в большинстве случаев) не имеют значения.
@ Предлагались различные альтернативные подходы для устранения этой несовместимости, однако они все оказались весьма неудачными, и чувствовалось, что было бы лучше один раз сделать надлежащую вещь, а не иметь постоянную головную боль.
@ Однако, ситуация относительно управляемых ссылочных параметров несколько отличается. Напомним, что управляющий параметр это параметр тэгового типа, а примитивная операция это операция объявленая рядом с теговым типом в спецификации пакета (или унаследованная от предка). Рассмотрим:
|
@ Здесь тип TT - теговый, а процедура Op - примитивная операция, и следовательно ссылочный параметр X - управляющий.
@ В этом случае анонимный ссылочный тип (подтип) все еще запрещает пустой указатель, поскольку в Аде 95 нулевой указатель запрещается как параметр. Причина этого состоит в том, что управляющие параметры обеспечивают тэг для диспетчеризации, а пустой указатель не имеет никакого значения тэга. Напомним, что каждый управляющий параметр должен иметь свой тэг. Мы можем добавить not null к спецификации параметра, если пожелаем, но требовать это явно для всех управляющих параметров было бы слишком большой несовместимостью. Но в новых программах мы должны поощрять писать not null явно чтобы избежать беспорядка во время обслуживания.
@ Следующее правило относится к нулевому исключению. Оно состоит в том, что тип наследуемый из типа, который исключает пустой указатель, также исключает пустой указатель. Рассмотрим:
|
@ здесь Another_Ref_NNT также исключает пустой указатель. С другой стороны, если мы наследуем из ссылочного типа, который не исключает пустой указатель тогда, производный тип может либо исключать пустой указатель либо нет:
|
@ тогда Another_Ref_T не исключает пустой указатель, но ANN_Ref_T действительно исключает пустой указатель.
@ Технический нюанс здесь в том, что все ссылочные типы, включая анонимные в Аде 2005 разрешают пустой указатель как значение, тогда как в Аде 95 - нет. Только подтипы в Аде 2005 не всегда имеют пустой указатель как значение. Напомним, что Ref_NNT - фактически изначально именованный подтип.
@ Важное преимущество всех ссылочных типов, разрешающих пустой указатель в качестве значения состоит в том, что это значительно упрощает интерфейсную связь с языком C. Если параметр в C имеет тип *t, тогда соответствующий параметр на Аде может иметь ссылочный тип T, и если подпрограмма C нуждается в пустом указателе, тогда не возникает никаких проблем. На Аде 95 это было настоящей головной болью.
@ Явное нулевое исключение может также использоваться в объявлениях объектов таких как constraint. Рассмотрим:
|
@ Заметим, что мы должны выполнить явную инициализацию X, иначе инициализация по умолчанию пустым указателем вызовет исключение Constraint_Error.
@ До некоторой степени нулевые исключения имеют много общего с ограничениями. В примере:
|
@ возникнет исключение Constraint_Error потому, что 0-е значения не разрешается для подтипа Y. Различие здесь в том, что в случае X выполняется проверка Access_Check, тогда как в случае Y это - Range_Check.
@ Факт, что нулевое исключение фактически не классифицировано как ограничение посредсвом синтаксиса для subtype_indication, который в Аде 2005:
|
@ Явное нулевое исключение может также использоваться в объявлениях подпрограмм следующим образом:
|
@ Но различие между нулевыми исключениями и ограничениями в том, что, хотя мы можем использовать нулевое исключение в спецификации параметра, мы не можем использовать ограничение в спецификации параметра. Таким образом:
|
@ Но нулевые исключения походят на ограничения когда они оба используются в определении соответствия подтипа и статического соответствия.
@ Мы также можем использовать нулевое исключение с ссылочными типами на подпрограмму, включая защищенные подпрограммы.
|
@ и так далее.
@ Нулевое исключение также может использоваться в переименованиях подпрограмм и объектов. Мы рассмотрим переименования подпрограмм здесь и обсудим переименования в следующем разделе, когда будем рассматривать анонимные ссылочные типы. Это - область, где есть существенное различие между нулевыми исключениями и ограничениями.
@ Напомним, что если объект переименован тогда, любые изменения ограничения игнорируются. Мы могли бы иметь:
|
@ Вызов процедуры Q вызовет исключение Constraint_Error, потому что -0- не позволенное значение для типа Positive. Ограничение Natural при переименовывании полностью игнорируется (Ада ведёт себя так с незапамятных времён).
@ Мы предпочли бы, чтобы этот вид специфического поведения не простирался на нулевые исключения.
@ Однако, мы уже имеем проблему, что управляющий параметр всегда исключает пустой указатель, даже если это явно не указано. Таким образом, общее правило действующее с нулевыми исключениями состоит в том, что "нулевое исключение выполняется всегда".
@ Другими словами, если мы назначаем нулевое исключение, тогда, объект должен исключать пустой указатель всегда; однако, если мы не указываем нулевое исключение тогда, объект может исключать пустой указатель по другим причинам (например в случае управляющего параметра).
@ Рассмотрим:
|
@ Вызов процедуры Q возбуждает исключение Constraint_Error, потому что параметр исключает пустой указатель даже при том, что нет никакого явного нулевого исключения в переименовывании. С другой стороны (мы предполагаем, что X не управляющий параметр),
|
@ является незаконным, потому что нулевое исключение при переименовывании не допускается.
@ Однако, если процедура P является примитивной операцией типа T, и при этом X является управляющим параметром тогда, переименовывание с нулевым исключением разрешается.
@ Должны быть предприняты меры, когда само переименовывание используется как примитивная операция. Рассмотрим:
|
@ Процедура One - примитивная операция типа T, его параметр X - управляющий и так исключает пустой указатель даже при том, что это явно не заявлено. Однако, объявление Two незаконно т.к. оно пробует быть операцией диспетчеризации T, и поэтому его управляющий параметр X должен исключить пустой указатель. Но Two - переименовывание Deux, соответствующий параметр которого не исключает пустой указатель и, таким образом, переименовывание незаконно. С другой стороны, объявление Three разрешается, потому что параметр Trois действительно исключает пустой указатель.
@ Другая область, которая нуждалась в унификации касается констант. В Аде 95 именованный ссылочный тип может быть ссылкой к постоянному типу, а не ссылкой к типу переменной, таким образом, тип Ref_CT - ссылка на константу T; Напомним, что это означает, что мы не можем изменить значение объекта типа T через ссылку.
@ Напомним, что Ада 95 ввела более общие ссылочные типы, тогда как в Аде 83 все ссылочные типы были определенным пулом и могли только обратиться к значениям, полученным от системной программы распределения памяти. Ссылочный тип в Аде 95 может также ссылаться на любой объект помеченный aliased при условии, что ссылочный тип объявлен с атрибутом all таким образом:
|
@ Таким образом, Ада 95 имеет три вида именованных ссылочных типа:
|
@ Но в Аде 95 не разрешается различие между переменными и постоянными ссылочными параметрами. Ада 2005 исправляет это, разрешая константу с ссылочными параметрами. Таким образом, мы можем написать:
|
@ Заметим однако, что не всем разрешены сылочные параметры. Обычные объекты могут быть константами или переменными:
|
@ и ссылочные параметры следуют за этим образцом. Их называют ссылочными типами, которые являются аномальными из-за необходимости отличать pool specific типы для совместимости с Адой 83 и последующей потребностью их вести.
@ В Аде 2005 ссылочные параметры могут принять следующие четыре формы:
|
@ Кроме того, как упомянуто выше, управляющие параметры всегда исключают пустой указатель, даже если это явно не заявлено (в том случае P1 и P3 являются эквивалентными). Управляющие параметры могут также быть константными, когда P2 и P4 эквивалентны.
@ Подобные правила применяются к ссылочным дискриминантам; таким образом, они могут исключить пустой указатель и/или быть ссылкой к константе.
2010-10-24 00:26:54
. .