如果我打开那些编译器检查指令,这是一些导致范围检查错误和溢出错误的代码的精简版本。我理解为什么这会导致溢出,在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评估它时,它显示“Undeclared identifier:'param1'”。
答案 0 :(得分:18)
关于范围检查的文件说明:
$ 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 =没有
测试是(伪代码),XE2采用32位模式:
number := High(TNumber);
number := number + 1;