【问题标题】:Cause of Range Check Error (Delphi)范围检查错误的原因(Delphi)
【发布时间】:2012-07-24 09:40:55
【问题描述】:

如果我打开那些编译器检查指令,这里有一些代码会导致范围检查错误和溢出错误的精简版本。我理解为什么这会导致溢出,在 C1 的乘法中,它似乎可能超过数据类型的最大值。但是为什么这也会触发范围检查错误呢? Delphi 的文档和其他关于堆栈溢出的帖子听起来像是范围检查错误通常是针对超出范围的数组访问。但我没有访问它所说的导致范围检查错误的行上的数组。也许它分配给param1?但是,如果是这样,那为什么会是范围检查而不是溢出错误呢?

const
  C1 = 44001;
  C2 = 17999;

function fxnName(..other params...; param1: Word): String;
var
  someByte: byte;
begin
  // some code
  // by now we're in a loop. the following line is where it breaks to in the debugger: 
  param1 := (someByte + param1) * C1 + C2;
  // more code
end;

如果它是相关的,当它在调试器中的该行中断时,所有值看起来都符合预期,除了 param1,当我要求 Delphi 评估它时显示“未声明的标识符:'param1'”。

【问题讨论】:

  • 我怀疑这只是因为范围检查发生在溢出检查之前,并且一旦引发范围检查异常,溢出检查就不会发生。 (不确定顺序,所以只是怀疑。)

标签: delphi delphi-7


【解决方案1】:

关于范围检查状态的文档:

$R 指令启用或禁用范围检查代码的生成。在 {$R+} 状态下,所有数组和字符串索引表达式都被验证是否在定义的范围内,并且所有对标量和子范围变量的赋值都被检查是否在范围内。如果范围检查失败,则引发 ERangeError 异常(如果未启用异常处理,则程序终止)。

所以这里的原因是分配给一个标量值,它被传递一个超过上限的值。

另请参阅docwiki Simple Types,了解简单类型和子范围类型的范围检查错误。

例子:

{$R+} // Range check on
var
  w1,w2 : word;
begin
  w1 := High(word);
  w1 := w1 + 10; // causes range-check error on assignment to w1 (upper range passed)
  w2 := 0;
  w2 := w2 - 10; // causes range-check error on assignment to w2 (lower range passed)
end;

对所有平台无关整数类型的所有 $R 和 $Q 组合的总结测试:

            R+Q+  R+Q-  R-Q+
 ShortInt    R     R     x
 SmallInt    R     R     x
 Integer     O     x     O
 LongInt     O     x     O
 Int64       O     x     O
 Byte        R     R     x
 Word        R     R     x
 LongWord    O     x     O
 Cardinal    O     x     O
 UInt64      O     x     O

R=范围错误; O=溢出错误; x=没有

并且测试是(伪代码)在 32 位模式下使用 XE2:

number := High(TNumber);
number := number + 1;

【讨论】:

  • @DavidHeffernan,阅读文档,刚刚测试了代码,它确实会产生范围检查错误。您必须在 之后阅读,即它声明对标量和子范围变量的所有赋值都已检查。
  • 如果数据类型是整数估计会溢出错误
  • @DavidHeffernan 如果在Integer 类型上执行计算,当然可以,但是i := i + Int64(1); 应该(未经测试)当i 是@987654328 时会导致范围错误@ 值为MaxInt
  • 漂亮的桌子!综上所述,type range error,type => 32 bytes -> 溢出错误。很奇怪..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-18
  • 2021-06-20
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
  • 2021-10-13
  • 2014-08-20
相关资源
最近更新 更多