从不使用预定义的真实类型?

Never use pre-defined real types?

我开始通过阅读 ADA Distilled 来学习 Ada 语言。 在第 3.8 章中说:

The Ada programmer never uses pre-defined real types for safety-critical, production quality software.

我想知道这到底意味着什么,我应该怎么做而不是使用预定义的真实类型。这是否意味着我不能使用整数?

这意味着您应该"always"[*]定义与您的问题匹配的类型。

[*] 如果您的问题包括处理字符串,建议您为此使用标准 String 类型(并在其中使用 Positive 进行索引)。还有其他类似的例外情况,但除非您能解释为什么应该使用预定义类型,否则不要这样做。

"Never" 在我看来太强了。

"Never in safety critical software" 完全是另一回事,意见(尤其是我的意见)并不重要。

对于 non-critical 代码(我的大部分编程都是 non-critical,我使用 Ada 只是因为调试 C 花费了我太多时间)pre-defined 类型是可以的,但是定义你自己的真的不需要任何时间。

为了学习 Ada,使用(尝试)定义您自己的实数和整数类型只是为了看看它是如何工作的。特别是对于整数类型,习惯数组索引的特殊类型的想法,以消除缓冲区溢出和边界错误。

但是在学习该语言的其他方面时,您可以只使用 pre-defined 类型来达到许多目的,以节省精力并专注于您要学习的内容。

但是,如果您的 Ada 程序可能致残或致死,或者损失大笔资金,请忽略上述内容并听取 "Ada Distilled" 的建议。

我不确定作者在想什么,我希望他能解释一下。我个人讨厌没有任何解释的规则,希望读者能简单地接受它作为"received wisdom"。 (没有反对作者的意思——我知道他是个好人。)

也就是说,这是我的想法:

Ada 的第一个版本,Ada 83,说有预定义的 IntegerFloat 类型,实现可以提供其他类型,如 Long_IntegerLong_Float.不过,该语言并未对实现的定义设置任何界限。理论上,一个实现可以提供 2 位宽的 Integer 类型,只包含从 -2 到 +1 的值。 (这对编译器的销售不利,但会符合语言定义。)因为不能保证预定义的类型足够大或(在浮点数的情况下)足够精确以满足程序的需要,所以鼓励程序员始终定义自己的整数和 floating-point 类型,指定所需的范围和精度。

Ada 95 添加了一些约束:Integer 必须至少在 -32768..32767 范围内保存值,如果实现支持 Float 必须支持 6 位小数精度 floating-point 精确的数字。因此,避免使用预定义类型的一些动机已经​​消失。如果您的计算不需要超过 6 位的精度,那么 Float 应该没问题。如果 Float 精度低于 6 位,那么实现根本无法支持 6 位,并且您通过定义自己的浮点数也不会做得更好。因此,如果您知道永远不需要迁移到不同的编译器,那么您可能没问题。

不过,您可能 运行 遇到整数类型不会出现的可移植性问题。如果 Integer 变量永远不会保存超出范围 -32768..32767 的值,那么从 16 位 Integer 类型的机器转移到另一台 24 位机器时应该不会遇到任何问题-bit Integer 或 32 位 Integer 或其他任何东西——计算应该是一样的。但我不能对 floating-point 数字说同样的话。 Floating-point 舍入意味着如果将 Float 是 32 位 IEEE 浮点数的程序以一种方式运行,则如果移动到 Float 是 64 位 IEEE 浮点数的机器,则其行为可能会有所不同,或者反之亦然。如果您有一个程序,并且您的 32 位浮点数突然全部更改为 64 位浮点数,则需要非常彻底地重新测试。很有可能有些东西会坏掉。

如果您定义自己的 floating-point 类型,您应该没问题,至少如果您将实现限制在那些使用 IEEE 浮点数的情况下。 (现在大多数机器都是这样,尽管可能仍然有一些 VAX 使用它们自己的 floating-point 格式。如果仍然有不少这样的野兽仍在使用,我不会感到惊讶。)如果您需要在 IEEE-float 和非 IEEE-float 机器之间迁移,那么即使编写您自己的 floating-point 定义也可能不够;精度可能略有不同,结果可能不完全相同。