Ada:违反 "No_Exception_Propagation"- 第 2 部分

标签 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 (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;

当我编译它时:

gnatmake -gnatw.e no_propagation.adb

我收到以下警告:

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

Q1。当我在 Concat 函数的声明 block 中有异常处理程序时,为什么会收到“Constraint_Error”可能导致未处理异常的警告?

Q2。将两个字节一起粘贴到 Byte_Array 中怎么会产生约束错误?

最佳答案

我认为您的代码触发了来自 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;

但是你会得到同样的警告;这一次,我认为,因为需要将异常传播到引发它的范围之外。如果是这样,这似乎是规则的不幸后果,或者可能是实现问题:No_Exception_PropagationGNAT extension ,

This restriction guarantees that exceptions are never propagated to an outer subprogram scope. The only case in which an exception may be raised is when the handler is statically in the same subprogram, so that the effect of a raise is essentially like a goto statement. Any other raise statement (implicit or explicit) will be considered unhandled. Exception handlers are allowed, but may not contain an exception occurrence identifier (exception choice). In addition, use of the package GNAT.Current_Exception is not permitted, and reraise statements (raise with no operand) are not permitted.

至于问题 2,这看起来像是另一个编译器问题。 Byte_Array'(Input_1 & Input_2) 会导致警告,Byte_Array'(Input_1, Input_2) 不会。

无论哪种情况,您都会在调用 Concat 时收到相同的警告。

最好的方法可能是使用 -gnatw.X 来抑制所有这些警告,“关闭非本地异常的警告”(这应该是默认设置,但我猜使用 No_Exception_Propagation 打开警告。

关于Ada:违反 "No_Exception_Propagation"- 第 2 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42261940/

相关文章:

gcc - Mac OS 的链接器问题

用于初始化动态分配数组的 Ada 语法

pass-by-reference - := and => in Ada?有什么区别

ada - 动态数组大小在 ada 中运行时确定

ada - ada中的类型转换

ada - 关于 ADA 中 protected 数据对象

generics - 有没有办法在 Ada(特别是 GNAT)中创建和重用方面集?

netbeans - Ada 与 Netbeans

ada - 如何打印 ada 访问变量指向的地址?