我有以下代码将两个字节组合成一个字节数组:
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函数中的declare块中有异常处理程序时,为什么会收到“Constraint_Error”可能导致未处理异常的警告?
Q2。如何将两个字节粘贴到Byte_Array中会产生约束错误?
答案 0 :(得分: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;
答案 1 :(得分: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;
但你会得到同样的警告;这一次,我认为,因为异常需要传播到它被引发的范围之外。如果是这样,这似乎是规则的不幸后果,或者可能是实施问题:No_Exception_Propagation
是GNAT extension,
此限制可确保异常永远不会传播到外部子程序范围。可能引发异常的唯一情况是处理程序静态地位于同一子程序中,因此加注的效果基本上类似于goto语句。任何其他加注声明(隐式或显式)将被视为未处理。允许异常处理程序,但可能不包含异常发生标识符(异常选择)。此外,不允许使用GNAT.Current_Exception包,并且不允许重新加载语句(不使用操作数引发)。
对于问题2,这看起来像另一个编译器问题。 Byte_Array’(Input_1 & Input_2)
导致警告,Byte_Array'(Input_1, Input_2)
没有。
在任何一种情况下,您都会在致电Concat
时收到相同的警告。
最好的方法可能是使用-gnatw.X
来抑制所有这些警告,“关闭非本地异常的警告”(这应该是默认值,但我想这些警告会在{ {1}})。