我不是一个Pascal的新手,但到现在为止,Delphi和
Free Pascal通常都会声明参数并返回值作为有符号整数,而我看到它们应该是正的.例如:
> Pos()返回Integer的类型.有可能是负面的吗?
> SetLength()将NewLength参数声明为一种Integer类型.字符串有负数吗?
> System.THandle声明为Longint.手柄有负数吗?
有很多像Delphi和Free Pascal这样的决定.这背后有什么考虑?
解决方法
在Pascal中,Integer(signed)是基础类型.所有其他整数类型是整数的子范围. (这在Borland方言中并不完全正确,在德尔福的TP和int64中给了longint,但足够接近).
一个重要的原因,如果计算的中间结果为负数,并且用无符号整数计算,范围检查错误将触发,并且由于大多数较旧的编程语言不会假定为2补数整数,所以结果(范围检查关闭)甚至可能是腐败的.
THandle案例简单得多. Delphi没有一个正确的32位无符号到D4,但只有一个31位的基数. (由于32位无符号整数不是整数的子范围,后来的unsigned int是int64的一个子集,将问题转移到仅在D2010左右添加的uint64)
所以在很多地方的标头签名类型中都使用winapi使用无符号类型,可能是为了避免在这些版本中第32位被破坏,并且自定义卡住了.
但是winapi案例与一般情况不同.
稍后添加一些Pascal(和Modula2 / 3)实现通过将整数设置为大于wordsize的大小来规避此陷阱,并要求所有数字类型声明适当的子范围,如下面的程序.
第一个主要假设是一切都是整数的一个子集,第二个允许编译器将几乎所有的东西缩小到适合寄存器,特别是如果cpu有一些大于字操作的操作. (如x86,其中32位* 32位mul给出64位结果,或者可以使用状态位检测词溢出溢出(例如,为添加而不进行完整的2 * wordize添加生成范围异常)
var x : 0..20; y : -10..10; begin // any expression of x and y has a range -10..20