程序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)
...
但是当我正在寻找另一块code时,我注意到我可以在边界之外使用索引,并且它不会引发任何异常......
我想知道它为什么会起作用,后果是什么? (例如,如果这部分内存不是保留而且我可以破坏它,......)
我已经搜索了其他问题,但没有找到好的问题......如果它存在,请不要犹豫,立即关闭此链接,谢谢。
答案 0 :(得分:6)
因为编译器不执行数据流分析。为了让编译器拒绝这个代码,它需要分析你的代码,并确保i
超出范围,编译器根本不这样做。要做到这一点,即使是更复杂的例子也需要编译器开发人员付出巨大努力。
如果您在切换范围检查时此代码将因运行时错误而失败,我个人认为通过向编译器添加此类数据流分析几乎无法获得。如果你没有启用范围检查,那么你真的应该。
使编译器执行范围检查的众多好处之一是,在许多情况下,您可以清除范围检查代码。这将使您的代码更清晰。但是,只有在完全控制索引并且可以静态分析代码时才能执行此操作。如果索引来自用户输入,那么显然您需要提供防止滥用的保护。
您问在没有范围检查的情况下运行此代码的后果是什么。好吧,行为没有定义,实际上任何事情都可能发生。最糟糕的情况是,该程序始终适合您,但对于您最重要的客户而言却失败了。