范围检查错误的原因 (Delphi) [英] Cause of Range Check Error (Delphi)
问题描述
这里是一些会导致范围检查错误和溢出错误的代码的精简版本,我是否应该打开这些编译器检查指令.我理解为什么这会导致溢出,在乘以 C1 时,它似乎可能超过数据类型的最大值.但是为什么这也会触发范围检查错误?Delphi 的文档和其他关于堆栈溢出的帖子听起来像是范围检查错误通常是针对超出范围的数组访问.但我没有访问它所说的导致范围检查错误的数组.也许它是对 param1 的分配?但是,如果是这样,那为什么会是范围检查而不是溢出错误呢?
Here's a condensed version of some code that causes both a Range check error and an overflow error, should I turn on those compiler check directives. I understand why this would cause an overflow, on the multiplication of C1, it seems likely it might exceed the data-type's max valude. But why would this also trigger a Range-check error? Delphi's documentation and other posts on stack overflow make it sound like range-check errors are usually for array accesses that are out of bounds. But I'm not accessing an array on the line it's saying is causing the range-check error. Perhaps its on the assignment to param1? But why would that be a range-check and not an overflow error, if so?
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'".
If it's relevant, when it breaks on that line in the debugger, all the values look as expected, except param1, which shows "Undeclared identifier: 'param1'" when I ask Delphi to evaluate it.
推荐答案
关于范围检查的文档说明:
The documents about range-checking states:
$R 指令启用或禁用范围检查代码的生成.在 {$R+} 状态下,所有数组和字符串索引表达式都被验证为在定义的范围内,并且所有对标量和子范围变量的赋值都被检查在范围内.如果范围检查失败,则会引发 ERangeError 异常(如果未启用异常处理,则程序将终止).
The $R directive enables or disables the generation of range-checking code. In the {$R+} state, all array and string-indexing expressions are verified as being within the defined bounds, and all assignments to scalar and subrange variables are checked to be within range. If a range check fails, an ERangeError exception is raised (or the program is terminated if exception handling is not enabled).
所以这里的原因是分配给一个标量值,它被传递到一个超过了上限的值.
So the reason here is the assignment to a scalar value, which is handed a value that has passed the upper range.
另请参阅 docwiki 简单类型,了解简单类型和子范围类型的范围检查错误.
See also docwiki Simple Types about range-checking errors on simple types and subrange 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 的所有组合的总结测试:
A summary test of all combinations of $R and $Q for all platform-independent integer types:
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=没有
R=Range error; O=Overflow error; x=Nothing
测试是(伪代码)在 32 位模式下使用 XE2:
And the test was(pseudo-code) with XE2 in 32-bit mode:
number := High(TNumber);
number := number + 1;
这篇关于范围检查错误的原因 (Delphi)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!