4

プログラムProject1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

var
  ints: array[1..2] of Integer = (0,0);
  i   : Integer;

begin
  ints[5] := 10;    // doesn't compile
  i := 5;
  ints[i] := 10;    // Seems to works
  Writeln(ints[i]); // and even display the value
  Readln;
end.

配列に境界を設定しましたints

通常、境界付き配列に値を設定する前に、をチェックしLow(ints)ます...しかし、別のコードHigh(ints)を探していたときに、境界の外側でインデックスを使用でき、例外が発生しないことに気付きました。 ..。。

なぜそれが機能するのか、そしてその結果はどうなるのか知りたいのですが?(たとえば、メモリのこの部分が予約されておらず、破損する可能性がある場合は、...)

他の質問を検索しましたが、良い質問が見つかりませんでした...存在する場合は、遠慮なくリンクを配置して、これを閉じてください。ありがとうございます。

4

1 に答える 1

6

コンパイラはデータフロー分析を実行しないためです。コンパイラがこのコードを拒否するには、コードを分析し、それiが範囲外であることを確認する必要があります。コンパイラは単にそうしません。適度に複雑な例でこれを行うには、コンパイラ開発者の非常に大きな努力が必要になります。

範囲チェックをオンにすると、このコードは実行時エラーで失敗するため、このようなデータフロー分析をコンパイラに追加しても得られるものはほとんどないと個人的に感じています。範囲チェックを有効にして実行していない場合は、実際に有効にする必要があります。

コンパイラに範囲チェックを実行させることの多くの利点の1つは、多くの場合、範囲チェックコードを消去できることです。これにより、コードがより明確になります。ただし、これを実行できるのは、インデックスを完全に制御でき、コードを静的に分析できる場合のみです。インデックスがユーザー入力からのものである場合は、明らかに、悪用に対する保護を提供する必要があります。

範囲チェックなしでこのコードを実行するとどうなるかを尋ねます。まあ、動作は定義されておらず、実際には何かが起こる可能性があります。最悪のシナリオは、プログラムは常に機能しますが、最も重要なクライアントにとっては重大な方法で失敗することです。

于 2012-05-15T11:38:52.370 に答える