2017-02-15 17 views
1

私はバイト配列に2つのバイトを組み合わせて、次のコードがあります。エイダ: - 「No_Exception_Propagation」の違反パート2

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関数内の宣言ブロックに例外ハンドラがあると、 "Constraint_Error"が未処理の例外を引き起こす可能性があるという警告が表示されるのはなぜですか?

Q2。 2バイトをまとめてByte_Arrayに貼り付けると、どのようにしてConstraint Errorが生成されますか?

+0

例外ハンドラは 'begin'の後のすべてを保護しますが、初期化はその前です...' End'プロシージャの前にハンドラが必要だと思います。 –

答えて

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_PropagationGNAT extension

でこの制限は、例外は外側のサブプログラムのスコープに伝播されることはありませんことを保証します。例外が発生する唯一のケースは、ハンドラが同じサブプログラムに静的に含まれている場合です。これにより、raiseの効果は本質的にgoto文のようになります。他のraise文(暗黙的または明示的)は未処理のものとみなされます。例外ハンドラは許可されていますが、例外発生識別子(例外選択肢)は含まれていない可能性があります。また、パッケージGNAT.Current_Exceptionの使用は許可されず、reraise文(オペランドなしのraise)は許可されません。

質問2については、これは別のコンパイラの問題のようです。 Byte_Array’(Input_1 & Input_2)は、警告を発生させ、Byte_Array'(Input_1, Input_2)は発生しません。

いずれの場合も、Concatの呼び出しで同じ警告が表示されます。

-gnatw.Xを使用してこれらの警告をすべて非表示にすることをお勧めします(デフォルト以外の警告が表示されますが、警告はNo_Exception_Propagationで有効になると思います)。

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; 
関連する問題