4

方案项目1;

{$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)and ......但是当我在寻找另一段代码时,我注意到我可以在边界之外使用索引并且它不会引发任何异常...High(ints)

我想知道它为什么起作用以及结果是什么?(例如,如果这部分内存没有保留,我可以破坏它,...)

我已经搜索了其他问题,但没有找到好的问题...如果存在,请不要犹豫,放置链接并关闭此问题,谢谢。

4

1 回答 1

6

因为编译器不执行数据流分析。为了让编译器拒绝此代码,它需要分析您的代码并确保它i超出范围,并且编译器根本不会这样做。对更复杂的示例执行此操作需要编译器开发人员付出巨大的努力。

由于如果您打开范围检查,此代码将失败并出现运行时错误,因此我个人认为将此类数据流分析添加到编译器中几乎没有什么收获。如果您没有在启用范围检查的情况下运行,那么您确实应该这样做。

让编译器执行范围检查的众多好处之一是,在许多情况下,您可以删除范围检查代码。这将使您的代码更加清晰。但是,只有在完全控制索引并且可以静态分析代码时才能执行此操作。如果索引来自用户输入,那么显然您需要提供防止滥用的保护。

你问在没有范围检查的情况下运行这段代码会有什么后果。好吧,行为没有定义,真的任何事情都可能发生。最坏的情况是该程序总是对您有效,但对您最重要的客户却以一种关键的方式失败。

于 2012-05-15T11:38:52.370 回答