永远不要使用预定义的真实类型?

时间:2016-01-25 13:05:42

标签: ada safety-critical

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

  

Ada程序员从不使用预定义的真实类型   安全关键的生产质量软件。

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

3 个答案:

答案 0 :(得分:4)

我不确定作者在想什么,我希望他已经解释过了。我个人讨厌规则而没有任何解释,希望读者只是接受它作为“获得智慧”。 (没有任何反对作者 - 我知道他是个好人。)

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

Ada的第一个版本Ada 83表示有预定义的IntegerFloat类型,并且这些实现可能会提供其他类型,例如Long_IntegerLong_Float。但是,该语言没有对实现的定义进行任何限制。从理论上讲,实现可以提供2位宽的Integer类型,仅保留-2到+1的值。 (这对于编译器销售来说会很糟糕,但是会符合语言定义。)因为不能保证预定义类型足够大或者(在浮点数的情况下)精确到足以满足程序的需要,所以鼓励程序员始终定义自己的整数和浮点类型,指定所需的范围和精度。

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

但是,您可能遇到整数类型不会出现的可移植性问题。如果Integer变量永远不会保存在-32768..32767范围之外的值,那么从具有16位Integer类型的计算机移动到具有24的{24}的另一台计算机时,您不会遇到任何问题-bit Integer或32位Integer或其他 - 计算应该相同。但我不能对浮点数说同样的话。浮点舍入意味着如果将Float移动到Float是64位IEEE浮点数的机器,那么行为class Product { /** * @ORM\Id * @ORM\Column(type="integer", nullable=false) * @ORM\GeneratedValue(strategy="IDENTITY") */ protected $id; /** * @var string * * @ORM\Column(name="name", type="string", length=255, nullable=false) */ protected $name; /** * @var \Doctrine\Common\Collections\Collection|UserGroup[] * * @ORM\ManyToMany(targetEntity="Catalog\Model\Entity\Category", inversedBy="product") * @ORM\JoinTable( * name="product_category", * joinColumns={ * @ORM\JoinColumn(name="product_id", referencedColumnName="id") * }, * inverseJoinColumns={ * @ORM\JoinColumn(name="category_id", referencedColumnName="id") * } * ) */ protected $categories; } 是32位IEEE浮点运算的程序可能会有不同的行为,反之亦然。如果你有一个程序,并且你的32位浮点数突然全部变为64位浮点数,那么需要对它进行彻底的重新测试。有一些不错的机会会破坏。

但是,如果您定义自己的浮点类型,那么您应该没问题,至少如果您将实现局限于那些使用IEEE浮点数的实现。 (现在大多数机器都是这样,虽然可能还有一些VAX仍在使用他们自己的浮点格式。如果还有不止一些这些野兽仍在使用中,我不会感到惊讶。)如果你需要在IEEE-float和非IEEE-float机器之间进行迁移,然后甚至编写自己的浮点定义可能还不够;精度可能略有不同,结果可能不完全相同。

答案 1 :(得分:2)

在我看来,“从不”太强大了。

“从不在安全关键软件中”是另一回事,意见(特别是我的意见)并不重要。

对于非关键代码(我的大部分编程都是非关键代码,我使用Ada只是因为调试C花了我太长时间)预定义的类型没问题,但定义自己的类型确实不需要时间。 Possibly relevant Q&A...

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

但在学习该语言的其他方面时,您可以将预定义类型用于多种用途,以节省工作量并专注于您尝试学习的内容。

但是,如果您的Ada程序可能会伤害或杀死某人,或者损失大笔金钱,那么请忽略上述内容并接受“Ada Distilled”的建议。

答案 2 :(得分:1)

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

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