Rationale for Ada 2005: Exceptions, generics etc

RUSTOP
BACKNEXT

ENG

2. Exceptions

@ There are two minor improvements in this area.

@ One concerns the detection of a null exception occurrence which might be useful in a routine for analysing a log of exceptions. This is tricky because although a constant Null_Occurrence is declared in the package Ada.Exceptions, the type Exception_Occurrence is limited and no equality is provided. So the obvious test cannot be performed.

@ We can however apply the function Exception_Identity to a value of the type Exception_Occurrence and this returns the corresponding Exception_Id. Thus we could check to see whether a particular occurrence X was caused by Program_Error by writing

  1        if Exception_Identity (X) = Program_Error'Identity then

@ However, in Ada 95, applying Exception_Identity to the value Null_Occurrence raises Constraint_Error so we have to resort to a revolting trick such as declaring a function as follows

  1        function Is_Null_Occurrence (X : Exception_Occurrence) return Boolean is
  2                Id : Exception_Id;
  3        begin
  4                Id := Exception_Identity (X);
  5                return False;
  6        exception
  7                when Constraint_Error => return True;
  8        end Is_Null_Occurrence;

@ We can now write some general analysis routine as

  1        procedure Process_Ex (X : in Exception_Occurrence) is
  2        begin
  3                if Is_Null_Occurrence (X) then -- OK in Ada 95
  4                        -- process the case of a null occurrence
  5                else
  6                        -- process proper occurrences
  7                end if;
  8        end Process_Ex;

@ But the detection of Constraint_Error in Is_Null_Occurrence is clearly bad practice since it would be all too easy to mask some other error by mistake. Accordingly, in Ada 2005, the behaviour of Exception_Identity is changed to return Null_Id when applied to Null_Occurrence. So we can now dispense with the dodgy function Is_Null_Occurrence and just write

  1        procedure Process_Ex (X : in Exception_Occurrence) is
  2        begin
  3                if Exception_Identity (X) = Null_Id then -- OK in 2005
  4                        -- process the case of a null occurrence
  5                else
  6                        -- process proper occurrences
  7                end if;
  8        end Process_Ex;

@ Beware that, technically, we now have an incompatibility between Ada 95 and Ada 2005 since the nasty function Is_Null_Occurrence will always return False in Ada 2005.

@ Observe that Constraint_Error is also raised if any of the three functions Exception_Name, Exception_Message, or Exception_Information are applied to the value Null_Occurrence so the similar behaviour with Exception_Identity in Ada 95 is perhaps understandable at first sight.

@ However, it is believed that it was not the intention of the language designers but got in by mistake.

@ Actually the change described here was originally classified as a correction to Ada 95 but later reclassified as an amendment in order to draw more attention to it because of the potential incompatibility.

@ The other change in the exception area concerns the raise statement. It is now possible (optionally of course) to supply a message thus

  1        raise An_Error with "A message";

@ This is purely for convenience and is identical to writing

  1        Raise_Exception (An_Error'Identity, "A message");

@ There is no change to the form of raise statement without an exception which simply reraises an existing occurrence.

@ Note the difference between

  1        raise An_Error; -- message is implementation defined

@ and

  1        raise An_Error with ""; -- message is null

@ In the first case a subsequent call of Exception_Message returns implementation defined information about the error whereas in the second case it simply returns the given message which in this example is a null string.

@ Some minor changes to the procedure Raise_Exception are mentioned in Section 4 below.

@ There are also additional functions in the package Ada.Exceptions to return the name of an exception as a Wide_String or Wide_Wide_String. They have identifiers Wide_Exception_Name and Wide_Wide_Exception_Name and are overloaded to take a parameter of type Exception_Id or Exception_Occurrence. The lower bound of the strings returned by these functions and by the existing functions Exception_Name, Exception_Message and Exception_Information is 1 (Ada 95 forgot to state this for the existing functions). The reader will recall that similar additional functions (and forgetfulness) in the package Ada.Tags were mentioned in the paper on the object oriented model.

Rationale for Ada 2005: Exceptions, generics etc

@ENGRUSTOPBACKNEXT

2. Исключения

@ Есть два небольших усовершенствования этой области.

@ Первое касается обнаружения нулевого вхождения исключения, которое могло бы быть полезным в подпрограмме для анализа журнала регистрации исключений. Это является хитрым потому что, хотя константа Null_Occurrence объявлена в пакете Ada.Exceptions, тип Exception_Occurrence является ограниченым и следовательно не поддерживает никакое равенство. Таким образом, очевидный тест не может быть выполнен.

@ Мы можем, однако, применить функцию Exception_Identity к значению типа Exception_Occurrence которая возвращает Exception_Id. Таким образом, мы можем выяснить, было ли специфическое вхождение X вызвано Program_Error при написании:

  1        if Exception_Identity (X) = Program_Error'Identity then

@ Однако, в Аде 95 при попытке применить Exception_Identity к значению Null_Occurrence возникает исключение Constraint_Error, и таким образом, мы должны прибегнуть к некоторой уловке объявляя функцию следующим образом:

  1        function Is_Null_Occurrence (X : Exception_Occurrence) return Boolean is
  2                Id : Exception_Id;
  3        begin
  4                Id := Exception_Identity (X);
  5                return False;
  6        exception
  7                when Constraint_Error => return True;
  8        end Is_Null_Occurrence;

@ Мы можем теперь написать некоторую общую подпрограмму анализа так:

  1        procedure Process_Ex (X : in Exception_Occurrence) is
  2        begin
  3                if Is_Null_Occurrence (X) then -- OK in Ada 95
  4                        -- process the case of a null occurrence
  5                else
  6                        -- process proper occurrences
  7                end if;
  8        end Process_Ex;

@ Но обнаружение Constraint_Error в Is_Null_Occurrence - плохая практика, так как остаётся опасность пропустить какую-нибудь другую ошибку. Соответственно, в Аде 2005 Exception_Identity возвращает Null_Id когда имеется Null_Occurrence. Таким образом, мы можем теперь обойтись без изворотливой функции Is_Null_Occurrence и написать:

  1        procedure Process_Ex (X : in Exception_Occurrence) is
  2        begin
  3                if Exception_Identity (X) = Null_Id then -- OK in 2005
  4                        -- process the case of a null occurrence
  5                else
  6                        -- process proper occurrences
  7                end if;
  8        end Process_Ex;

@ Остерегайтесь того что теперь у нас есть несовместимость между Адой 95 и Адой 2005, так как противная функция Is_Null_Occurrence в Аде 2005 будет всегда возвращать False.

@ Заметим, что также возбуждается исключение Constraint_Error если любая из трех функций Exception_Name, Exception_Message, или Exception_Information применена к значению Null_Occurrence, таким образом, подобное поведение с Exception_Identity в Аде 95 возможно понятно на первый взгляд.

@ Однако, полагается, что это не было специальным намерением разработчиков языка, а появилось по ошибке.

@ Фактически изменение, описанное здесь, было первоначально классифицировано как исправление к Аде 95, но позже повторно классифицировано как поправка, чтобы привлечь больше внимания к этому из-за потенциальной несовместимости.

@ Другое изменение в области исключений касается оператора raise. Теперь возможно (опционально, конечно) выдавать сообщение таким образом:

  1        raise An_Error with "A message";

@ Такая форма введена для удобства и идентична написанию:

  1        Raise_Exception (An_Error'Identity, "A message");

@ Нет никакого изменения к форме оператора raise без исключения, которое просто повторно поднимает существующее вхождение.

@ Отметьте различие между:

  1        raise An_Error; -- message is implementation defined

@ и

  1        raise An_Error with ""; -- message is null

@ В первом случае последующий вызов Exception_Message возвращает определённую реализацией информацию об ошибке, тогда как во втором случае оно просто возвращает данное сообщение, которое в этом примере является пустой строкой.

@ Небольшое изменение к процедуре Raise_Exception упомянуто в Секции 4 ниже.

@ В пакете Ada.Exceptions появились также дополнительные функции Wide_String и Wide_Wide_String возвращающие имя исключения. Они имеют идентификаторы Wide_Exception_Name и Wide_Wide_Exception_Name и перезагружены, чтобы взять параметр типа Exception_Id или Exception_Occurrence. Нижняя граница строк, возвращенных этими функциями и существующими функциями Exception_Name, Exception_Message и Exception_Information равна 1 (еденице) (В Аде 95 забыли указать это для существующих функций). Читатель напомнит, что подобные дополнительные функции (без последействий) в пакете Ada.Tags были упомянуты в статье посвящённой объектно-ориентированной модели.

@ ENG RUS

TOP BACK NEXT

2010-10-24 00:26:56

. .