我开始通过阅读ADA Distilled来学习 Ada 语言。在第 3.8 章中它说:
Ada 程序员从不将预定义的真实类型用于安全关键的生产质量软件。
我想知道这到底意味着什么,我应该怎么做而不是使用预定义的真实类型。这是否意味着我不能使用整数?
我开始通过阅读ADA Distilled来学习 Ada 语言。在第 3.8 章中它说:
Ada 程序员从不将预定义的真实类型用于安全关键的生产质量软件。
我想知道这到底意味着什么,我应该怎么做而不是使用预定义的真实类型。这是否意味着我不能使用整数?
我不确定作者在想什么,我希望他能解释一下。我个人讨厌没有任何解释就流传下来的规则,希望读者简单地接受它作为“获得的智慧”。(没有反对作者——我知道他是个好人。)
也就是说,这是我的想法:
Ada 的第一个版本,Ada 83,说有预定义的Integer
和Float
类型,并且实现可以提供其他类型,比如Long_Integer
和Long_Float
。不过,该语言并未对实现的定义设置任何界限。理论上,实现可以提供Integer
2 位宽的类型,只保存从 -2 到 +1 的值。(这对编译器销售不利,但符合语言定义。)因为不能保证预定义的类型足够大或(在浮点数的情况下)足够精确以满足程序的需要,所以鼓励程序员始终定义自己的整数和浮点类型,以指定所需的范围和精度。
Ada 95 添加了一些约束:Integer
必须至少在 -32768..32767 范围内保存值,并且Float
如果实现支持精确的浮点数,则必须支持 6 位十进制数字的精度。因此,避免使用预定义类型的一些动机已经消失。如果您的计算不需要超过 6 位的精度,那么Float
应该没问题。如果Float
精度低于 6 位,则实现根本不支持 6 位,并且通过定义自己的浮点数不会做得更好。所以如果你知道你永远不需要迁移到不同的编译器,你可能没问题。
不过,您可能会遇到整数类型不会出现的可移植性问题。如果一个Integer
变量永远不会保存超出范围 -32768..32767 的值,那么从一台 16 位Integer
类型的机器移动到另一台 24 位Integer
或 32 位Integer
或其他类型的机器应该不会遇到任何问题—— - 计算应该是一样的。但我不能对浮点数说同样的话。浮点舍入意味着如果程序在Float
32 位 IEEE 浮点数的情况下以一种方式运行,则如果移动到Float
64 位 IEEE 浮点数的机器上,其行为可能会有所不同,反之亦然。如果您有一个程序并且您的 32 位浮点数突然全部变为 64 位浮点数,则需要对其进行非常彻底的重新测试。很有可能有些东西会坏掉。
但是,如果您定义自己的浮点类型,则应该没问题,至少如果您将实现限制为使用 IEEE 浮点的实现。(这是当今大多数机器,尽管可能仍有一些 VAX 使用它们自己的浮点格式。如果仍然有更多的这些野兽仍在使用,我不会感到惊讶。)如果你需要在 IEEE-float 和非 IEEE-float 机器之间迁移,那么即使编写自己的浮点定义也可能不够;精度可能略有不同,结果可能不完全相同。
在我看来,“从不”太强了。
“从不在安全关键软件中”是另一回事,意见(尤其是我的)并不重要。
对于非关键代码(我的大部分编程都是非关键的,我使用 Ada 只是因为调试 C 花费了我太长时间)预定义的类型是可以的,但是定义你自己的类型真的不需要任何时间。可能相关的问答...
为了学习 Ada,使用(玩弄)定义你自己的实数和整数类型来看看它是如何工作的。特别是对于整数类型,要习惯数组索引的特殊类型的想法,以消除缓冲区溢出和边界错误。
但是在学习语言的其他方面时,您可以将预定义的类型用于多种目的,以节省精力并专注于您想要学习的内容。
但是,如果您的 Ada 程序可能会致残或杀死某人,或者损失大量金钱,那么请忽略上述内容并听取“Ada Distilled”的建议。
这意味着您应该“始终”[*] 定义与您的问题匹配的类型。
[*] 如果您的问题包括处理字符串,建议您使用标准String
类型(以及Positive
在其中建立索引)。还有其他类似的例外,但除非您能解释为什么应该使用预定义类型,否则不要。