我习惯于C和C ++,其中大多数基本类型都有未指定的大小。我一直认为存在这些未指定的大小,以便在不同的架构中提供效率。
然而,在使用Rust和D等语言后, 我看到他们所有的基本/原始类型大多是固定的。
为什么D选择省略未指定尺寸的类型?
这不会妨碍机器的效率吗?
或者效率问题是否太小而不能超过固定类型的安全性?
我希望找到一些关于这个决定的文献,因为它是在两种语言没有固定大小作为基本类型之后制作的。希望这不是太基于意义的。
答案 0 :(得分:4)
在整数类型的大小实际上必须是系统特定的少数情况下,这些类型在D中没有固定的大小 - 例如size_t
和ptrdiff_t
(因为它们处理指针的大小和可以处理的内存量)。相反,它们是适当固定大小类型的别名。同样,存在用于与C代码交互的c_long
和c_long_double
等别名。那些需要基于他们所依赖的平台的可变大小,而对于像int
或long
这样的东西,D可能已经走了两条路,但它选择做其他的,现代的像Java和C#这样的语言确实使用了固定大小。
可以说,固定大小实际上提高可移植性。如果您编写的代码专门针对32位整数而不是未知大小的整数运行,那么您将在所有平台上获得一致的行为。在处理按位运算等问题时,这一点尤其重要,但它可以减少代码的问题。您不会因为在具有较小整数大小的新平台上编译程序而突然出现溢出问题。您不必遍历程序的每一行,以确保新平台上的整数大小能够与代码一起正常运行。使用固定的整数大小,您知道在更改平台时与整数大小相关的任何错误都不会发生。因此,您的代码是可移植的,使用可变大小的整数的代码不是。
在D代码中,size_t
有时会给程序员带来问题,因为它的大小与平台有关。在64位平台上编译的代码不会在32位平台上进行编译,如果它像将long
分配给size_t
那样,以及编译在32位上的代码平台不会在64位平台上编译,如果它确实像size_t
那样分配int
。 C / C ++有更少的问题,因为与D不同,它不会给出错误的转换变窄,但是走C / C ++路线并且没有犯这些错误意味着要抓住与之相关的错误会更难缩小转换率。如果D一般使用与平台相关的大小,那么任何编译器检查缩小转换都会导致在某些平台上导致错误而非其他平台的风险非常高,并且您将冒成与整数大小变化相关的错误(例如溢出)在某些平台上但不在其他平台上。使整数大小保持一致使得代码在不同平台上保持一致。
过去,在许多架构中确实使用"字大小"机器效率更高,但对于今天的架构,情况要复杂得多。 x86_64机器非常有效地在32位整数上运行,以至于64位整数在一般情况下效率会更高,而且32位整数使用更少内存的事实使得变量更有可能将保留在CPU缓存行中(以及只需要复制的内存较少),因此可以比64位整数更有效。但这取决于代码,确切的CPU和实际工作负载。我的理解是现代x86 CPU实际上模仿x86,但实际上比引擎盖下的更复杂(例如,它们实际上比x86微码必须使用更多的寄存器),并且它们可以做各种各样的机器在20或30年前没有做的疯狂的事情,以优化正在运行的东西。因此,情况是方式比以前更复杂,并且期望获得性能提升,因为您的整数大小与机器的字大小相匹配是一个巨大的过度简化。需要进行性能分析以确定哪种方法最适合特定应用,并且通常与您的期望完全相反。因此,尝试将整数大小与计算机的字大小相匹配并不一定会增加收益,这会使您的代码更容易出错。
就个人而言,多年来我一直在C ++中练习只使用int
来处理我知道相对较小并且不会完成任何按位操作的整数在他们。否则,我使用类似int32_t
和int64_t
的类型,我从不使用类似long
或short
的类型,因为一旦您需要开始使用不同的整数类型来获取特定类型对于整数的大小,使用固定大小的整数比使用在一定范围内的类型更不容易出错。而且还有很多其他人在做同样的事情。如果不这样做,如果你必须采用一个32位程序并将其移植到64位,你就会疯狂地祈祷你不会遇到各种奇怪的,难以接受的-track-down由整数大小的变化引起的错误,而如果你在任何地方都使用了固定大小的整数,你就不会有这些问题。
使用可变大小的整数类型只是乞求特定于平台的错误,而且它会提高性能常常值得怀疑。在这一点上,可变大小的整数似乎是一个C-ism,大多数语言都没有采用。从我所看到的,大多数要么主要是固定大小的整数类型,要么它们具有等价于BigInt
并且完全与硬件整数离婚。由于D是一种系统语言,它使用固定大小的整数,而不是使内置整数类型像BigInt
一样。