3

Ada コンパイラが範囲違反を通過させるのはなぜですか? 警告は表示されますが、いずれにせよエラーである場合、なぜそれを通過させるのでしょうか? これが有用な動作である実用的なシナリオはありますか?

そして最も重要なのは、型宣言がランタイム エンティティであるのはなぜですか? コード例の 3 行目は、事前に評価されると予想されるものです。実行可能ファイルに「作成」されるのは5行目だけだと思いました。なぜだめですか?それは役に立つものですか?ここで何かが欠けているか、誤解していますか?

with Ada.Text_IO;
procedure question is
    subtype Test is Natural range -1 .. 10;
begin
    Ada.Text_IO.Put_Line ("foobar");
end;

注: 結果は「type Test is new Natural range -1..10;」と同じです。

注: GNAT 4.6

4

1 に答える 1

8

この comp.lang.ada メッセージ-gnato -fstack-checkは、Gnat が対応する Ada コンパイラになるには、少なくともコマンド ライン オプションが必要であることを示唆しています。

ただし、それはここでは問題ではありません。コンパイラは範囲エラーについて警告します。Gnat を使用すると、次のようになります。

gnatmake -gnato -fstack-check question
question.adb:3:35: warning: static value out of range of type "Standard.Natural"
question.adb:3:35: warning: "Constraint_Error" will be raised at run time

実行時の明らかなエラー。

この場合、範囲が静的であるため、コンパイラはエラーをキャッチできた可能性があります。しかし、ご想像のとおり、一般に、次の例のように、実行時まで型を完全に決定することはできません。

with Ada.Text_IO;
with Ada.Command_Line;

procedure question is
   subtype Arguments is Natural range 1 .. Ada.Command_Line.Argument_Count;
begin
   for i in Arguments loop
      Ada.Text_IO.Put_Line ("Argument " & integer'image(i) & 
                            " is " & Ada.Command_Line.Argument(i)); 
      declare
         OneArg : constant String := Ada.Command_Line.Argument(i);
         subtype Characters is Natural range OneArg'range;
      begin
         null;  -- process the string here
      end;   
   end loop;
end;

ここでは、プログラムを実行するまでどちらのサブタイプもわかりません。

宣言ブロックは、私が非常に便利だと思う関連パターンを示しています。これは、変数 [サブ] 型を許可するだけでなく、可変サイズのオブジェクトをスタックに割り当てて、ループの反復ごとに自動的に再利用およびサイズ変更されるようにします。(他の言語と同様に、「new」で割り当て、「unchecked_deallocation」で解放することができますが、ここのように、必要がないことがよくあります)

于 2013-01-25T17:53:03.197 に答える