免费pascal子范围

时间:2014-01-10 16:02:14

标签: freepascal

我在mac Mavericks上使用fpc 2.6.2和Lazarus 1.0.12 我创建了一个像这样的变量

var
   MyVar : 7..200;

如果我在MyVar的子范围之外为7..200分配值,编译器仍会接受最多255的值。如果我分配256,则MyVar中的值变为{{ 1}}如果我分配0,则257变为1,依此类推。有人知道发生了什么事吗?

2 个答案:

答案 0 :(得分:3)

您尚未创建子范围。 :-)你已经声明了一个变量(使用var)。要正确创建子范围,首先要声明type

type
  TMyRange = 7..200;

然后,您将变量声明为type

var
  MyVar: TMyRange;

尝试分配超出该范围的值会导致编译器错误(例如,在带有范围检查的Delphi中):

MyVar := 201;
  

[dcc32错误] Project1.dpr(22):E1012常量表达式违反了子范围

启用范围检查通常是一个非常好的主意,这样编译器就能为您工作。 (打开溢出检查通常也是一个好主意,至少在开发过程中是这样。看看这个答案的其余部分是为了什么。)

就您所看到的行为而言,编译器将创建将保存子范围的最小尺寸序数类型(在本例中为Byte)。在这种情况下,您尚未声明一个子范围,而是一个简单的变量,编译器适合byte

由于一个字节可以保存来自0..255的值,并且您已声明了一个字节变量,因此它可以容纳的最大值为255.如果您指定256(并且未在编译器中打开溢出检查)选项),值溢出并回绕到最小值(零)+ 1(溢出的位数)。将257换行分配到最小值+ 2(再次,它溢出的量)。

答案 1 :(得分:1)

我相信FreePascal实际上创建了一个字节类型变量(因为它是包含给定范围的最小类型),它接受值0..255。数字256需要二进制的两个字节1和0(0000 0001 0000 0000)。分配给MyVar的最低得分。如果打开溢出检查,程序将引发异常而不是静默切割值。您可以通过-Co编译器参数或在源代码中使用{$Q-}{$Q+}编译器指令来执行此操作。

对于分配低于7或高于200的值,您可以通过使用命令行选项-Cr打开范围检查来避免这种情况。在源代码中,您还可以使用{$R-}{$R+}指令分别关闭和打开范围检查。

我建议在开发过程中始终打开溢出和范围检查。它确实有一些性能损失,因此如果它开始损害性能,你可以在发布时关闭它。