当前位置: 首页 > 知识库问答 >
问题:

范围检查错误的原因(Delphi)

范楚
2023-03-14

下面是一些代码的压缩版本,它会导致范围检查错误和溢出错误,如果我打开这些编译器检查指令的话。我理解为什么这会导致溢出,在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'”。

共有1个答案

云利
2023-03-14

有关范围检查的文档说明:

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

这里的原因是对一个标量值的赋值,这个标量值被赋予一个超过上限的值。

另请参见docwiki简单类型关于简单类型和子范围类型的范围检查错误。

例子:

{$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;
 类似资料:
  • 问题内容: java中是否有一种优雅的方法来检查int是否等于或大于或小于1。 例如,如果我检查周围。我想在上返回true ,因为4和6距5仅1。 有内置功能可以做到这一点吗?还是我最好这样写? 当然,以上代码很难看懂。那有更好的方法吗? 问题答案: 找到它们之间的绝对差异 基于@GregS关于溢出的评论,如果您给出的差值不能适合整数,您将获得一个溢出值 通过将其中一个参数强制转换为long 将返

  • 问题内容: 使用oracle中的范围分区,我们将大量数据按年值进行了分区。我们使用了范围分区,但每个分区仅包含一年的数据。当我们编写针对特定年份的查询时,oracle从该分区获取信息,但仍会检查年份是否是我们指定的年份。由于今年列不是索引的一部分,因此它从表中获取年份并进行比较。我们已经看到,每当查询去获取表数据时,它就会变得太慢。 我们可以以某种方式避免oracle比较年份值,因为我们确定知道分

  • 我有一个电子表格,由外部应用程序通过Google Sheets API编辑。然后,我在电子表格中有一个谷歌应用程序脚本函数,它由可安装的更改触发器调用。在开始时,此函数检查changeType是否等于“EDIT”,然后使用getActiveRange()检查编辑范围的最后一列。这很好,但有时返回的范围比实际编辑的范围小。功能代码: 例如,我们有一个空范围A3: G5。在这个范围内插入值后,它会正确

  • 问题内容: 任务是: 给出了一个非空的零索引字符串S。字符串S由N个大写英文字母A,C,G,T字符组成。 该字符串实际上代表DNA序列,大写字母代表单个核苷酸。 还为您提供了由M个整数组成的非空零索引数组P和Q。这些数组表示有关最小核苷酸的查询。我们将字符串S的字母表示为数组P和Q中的整数1、2、3、4,其中A = 1,C = 2,G = 3,T = 4,并假定A <C <G <T 。 查询K要求

  • 问题内容: 尝试此计算时出现溢出错误,但我不知道原因。 问题答案: 您要求math.exp计算的数字以十进制表示,超过110,000个数字。这稍微超出了double的范围,因此会导致溢出。

  • 问题内容: 该表用于存储会话(事件): 我们不想在范围之间产生冲突。 假设我们需要在 2010-01-05 至 2010-01-25之间 插入一个新会话。 我们想知道有冲突的会话。 这是我的查询: 结果如下: 有没有更好的方法来做到这一点? 小提琴 问题答案: 我曾经用日历应用程序进行过这样的查询。我想我使用了这样的东西: 更新 这肯定应该工作((ns,ne,es,ee)=(new_start,n