Ada:违反;无“例外”传播第二部分

Ada:违反;无“例外”传播第二部分,ada,Ada,我有以下代码,它将两个字节组合成一个字节数组: pragma Restrictions (No_Exception_Propagation); with Interfaces; use Interfaces; procedure No_Propagation is type Byte is new Unsigned_8; type Byte_Array is array (Natural range <>) of Byte; function Concat (

我有以下代码,它将两个字节组合成一个字节数组:

pragma Restrictions (No_Exception_Propagation);

with Interfaces; use Interfaces;

procedure No_Propagation is
   type Byte is new Unsigned_8;
   type Byte_Array is array (Natural range <>) of Byte;

   function Concat (Input_1 : Byte;
                    Input_2 : Byte)
                    return Byte_Array
   is
      Null_Array : Byte_Array (1 .. 0);
   begin
      declare
         Output : constant Byte_Array := Byte_Array'(Input_1 & Input_2);
      begin
         return Output;
      exception
         when Constraint_Error =>
            return Null_Array;
      end;
   end Concat;

   A, B : Byte;
begin
   A := 5;
   B := 0;
   declare
      C : Byte_Array := Concat(A, B);
   begin
      null;
   end;
end No_Propagation;
我得到以下警告:

no_propagation.adb:16:66: warning: pragma Restrictions (No_Exception_Propagation) in effect
no_propagation.adb:16:66: warning: "Constraint_Error" may result in unhandled exception
问题1。当我在Concat函数的declare块中有一个异常处理程序时,为什么我会收到一个警告,“Constraint\u Error”可能会导致未处理的异常


问题2。将两个字节粘贴到一个字节数组中怎么会产生约束错误?

一个更简单的程序版本是:

------------------------------------------------------------------
-- Simpler version of no propogation --
------------------------------------------------------------------
pragma Restrictions (No_Exception_Propagation);

with Interfaces; use Interfaces;

procedure No_Propagation2 is
   type Byte is new Unsigned_8;
   type Byte_Array is array (Natural range <>) of Byte;

   function Concat (Input_1 : Byte;
                    Input_2 : Byte)
                    return Byte_Array
   is
   begin
      return (Input_1, Input_2);
   end Concat;

   A : Byte := 5;
   B : Byte := 0;
   C : Byte_Array := Concat(A, B);
begin
   null;
end No_Propagation2;
------------------------------------------------------------------
--无传播的更简单版本--
------------------------------------------------------------------
杂注限制(无异常传播);
有接口;使用接口;
第2个步骤是
类型Byte是新的无符号_8;
类型Byte_Array是字节的数组(自然范围);
函数Concat(输入1:字节;
输入(2:字节)
返回字节数组
是
开始
返回(输入_1,输入_2);
端甲;
A:字节:=5;
B:字节:=0;
C:字节数组:=Concat(A,B);
开始
无效的
结束No_传播2;

我认为您的代码触发了GNAT发出的过分热情的警告

要回答问题1,您将看到更进一步的内容

no_propagation.adb:20:10: warning: pragma Restrictions (No_Exception_Propagation) in effect
no_propagation.adb:20:10: warning: this handler can never be entered, and has been removed
原因是您的异常处理程序太晚了,正如@BrianDrummond所建议的那样。你写

  declare
     Output : constant Byte_Array := Byte_Array'(Input_1 & Input_2);
  begin
     return Output;
  exception
     when Constraint_Error =>
        return Null_Array;
  end;
如果发生任何异常,它必须位于声明性区域中,该处理程序不包括该区域。你可以试着去写

      declare
         Output : constant Byte_Array := Byte_Array'(Input_1 & Input_2);
      begin
         return Output;
      end;
   exception
      when Constraint_Error =>
         return Null_Array;
但你会得到同样的警告;我认为这一次是因为异常需要传播到引发它的范围之外。如果是这样,这似乎是规则的一个不幸后果,或者可能是一个实现问题:
无异常传播

此限制保证异常不会传播到外部子程序范围。唯一可能引发异常的情况是处理程序静态地位于同一子程序中,因此引发的效果本质上类似于goto语句。任何其他raise语句(隐式或显式)将被视为未处理。允许使用异常处理程序,但不能包含异常发生标识符(异常选择)。此外,不允许使用包GNAT.Current_异常,也不允许使用reraise语句(raise不带操作数)

至于问题2,这看起来像是另一个编译器问题<代码>字节数组(输入1和输入2)导致警告,
字节数组(输入1和输入2)
不会

在任何一种情况下,调用
Concat
都会收到相同的警告


最好的方法可能是使用
-gnatw.X
,“关闭非本地异常的警告”(这应该是默认值,但我猜在
无异常传播时会打开警告).

异常处理程序在
开始之后保护所有内容
-但初始化在它之前。。。我认为在过程结束之前需要处理程序。
      declare
         Output : constant Byte_Array := Byte_Array'(Input_1 & Input_2);
      begin
         return Output;
      end;
   exception
      when Constraint_Error =>
         return Null_Array;