【问题标题】:Why are D's integral types fixed instead of unspecified?为什么 D 的整数类型是固定的而不是未指定的?
【发布时间】:2023-03-31 04:41:01
【问题描述】:

我习惯于 C 和 C++,其中大多数基本类型都有未指定的大小。我一直认为存在这些未指定的大小是为了提供跨不同架构的效率。

然而,在使用了 Rust 和 D 等语言之后,
我看到他们所有的基本/原始类型大多是固定的。

为什么 D 选择省略未指定尺寸的类型?
这不会影响跨机器的效率吗?
还是效率问题太微不足道而无法超过使用固定类型的安全性?

我希望找到一些关于这个决定的文献,因为它是在两种没有固定大小作为基本类型的语言之后做出的。希望这不是太基于选项。

【问题讨论】:

  • 相反的问题在这里:stackoverflow.com/questions/35517341/… 我喜欢这句话“它使语言更便携,但用这种语言编写的程序可能更不便携”。
  • Java 也有固定的类型大小。它使编写代码变得更容易,但不一定要尽可能快地编写代码。
  • 如果你真的想要,你可以使用平台特定的类型,例如 size_t 在 x86 上是 uint 在 x86_64 上是 ulongreal 在你的架构中为你提供尽可能高的精度.
  • 大多数以可移植性为目标的 C 程序无论如何都倾向于使用固定大小的别名...

标签: types size d sizeof fixed-width


【解决方案1】:

在整数类型的大小实际上必须是系统特定的少数情况下,这些类型在 D 中没有固定大小 - 例如size_tptrdiff_t(因为它们处理指针的大小以及可以寻址多少内存)。相反,它们是适当的固定大小类型的别名。同样,存在诸如c_longc_long_double 之类的别名用于与C 代码交互。那些需要根据它们所在的平台具有可变大小,而对于像intlong 这样的东西,D 可以选择任何一种方式,但它选择了其他现代语言,如 Java 和 C#使用固定尺寸。

可以说,固定尺寸实际上提高了可移植性。如果您编写的代码专门针对 32 位整数而不是未知大小的整数进行操作,那么您将在所有平台上获得一致的行为。这在处理诸如按位运算之类的东西时尤其重要,但它通常可以减少代码问题。您不会仅仅因为您在具有较小整数大小的新平台上编译程序而突然遇到溢出问题。您不必检查程序的每一行以确保新平台上的整数大小可以与代码正常工作。使用固定的整数大小,您知道任何与更改平台时整数大小相关的错误都不会发生。因此,您的代码具有可移植性,而使用可变大小整数的代码则不能。

在 D 代码中,size_t 有时会给程序员带来问题,正是因为它的大小取决于平台。在 64 位平台上编译的代码不会在 32 位平台上编译,如果它确实将 long 分配给 size_t,并且在 32 位平台上编译的代码不会在 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_tint64_t 之类的类型,而我从不使用longshort 之类的类型,因为一旦您需要开始使用不同的整数类型来获得特定大小的整数,错误就会更少- 倾向于使用固定大小的整数而不是使用特定范围内的类型。还有很多其他人也在做同样的事情。如果不这样做,如果您必须采用 32 位程序并将其移植到 64 位,您将疯狂地祈祷您不会遇到各种奇怪的、难以追踪的由整数大小的变化引起的错误,而如果你在任何地方都使用了固定大小的整数,你就没有这些问题。

使用可变大小的整数类型只是在乞求特定于平台的错误,而且它是否会提高性能通常是值得怀疑的。在这一点上,可变大小的整数似乎是后来的大多数语言都没有采用的 C 主义。据我所见,大多数要么主要具有固定大小的整数类型,要么具有与BigInt 等效的类型,并且完全脱离了硬件整数。由于 D 是一种系统语言,它使用固定大小的整数,而不是让内置的整数类型表现得像 BigInt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 2017-08-21
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多