【问题标题】:Why is int typically 32 bit on 64 bit compilers?为什么 int 在 64 位编译器上通常是 32 位?
【发布时间】:2013-07-03 14:44:39
【问题描述】:

为什么int 在 64 位编译器上通常是 32 位?当我开始编程时,我被教导 int 通常与底层架构具有相同的宽度。而且我同意这也是有道理的,我发现未指定宽度的整数与底层平台一样宽是合乎逻辑的(除非我们谈论的是 8 位或 16 位机器,int 的这么小的范围将几乎不适用)。

后来我了解到int 在大多数 64 位平台上通常是 32 位的。所以我想知道这是什么原因。对于存储数据,我更喜欢明确指定的数据类型宽度,因此这留下了int 的通用用法,它不会提供任何性能优势,至少在我的系统上我对 32 位和 64 位整数具有相同的性能.这样就剩下二进制内存占用了,虽然不会减少很多...

【问题讨论】:

  • 嗯,每个可用位长度都有一种类型是很好的,不是吗?不幸的是,int 失去了“原生字长”类型的地位。
  • 有很长的路要走。然后长长
  • 我建议阅读this 答案。 C++ 标准只要求符合一个范围。 32 位适合该范围,如果将其设为 32 位或 64 位,则取决于实现。
  • ... 和 int32_t, int64_t ....

标签: c++ compiler-construction int sizeof platform


【解决方案1】:

实施者的错误选择?

说真的,根据标准,“普通整数具有 执行架构建议的自然大小 环境”,这确实意味着 64 位 int 在 64 位 机器。人们很容易争辩说其他任何东西都是 不符合。但在实践中,问题更为复杂: 从 32 位 int 切换到 64 位 int不允许 大多数程序来处理大型数据集或其他任何东西(不像 从 16 位切换到 32 位);大多数程序可能是 受其他因素的限制。而且会增加 数据集的大小,从而减少局部性并减慢 程序下来。

最后(可能也是最重要的),如果 int 是 64 位, short 必须是 16 位或 32 位,你将无法指定另一个(除了 使用<stdint.h> 中的 typedef,其目的是这些 只应在非常特殊的情况下使用)。 我怀疑这是主要动机。

【讨论】:

  • 很容易争辩说“执行环境架构建议的自然大小”可能意味着 32 位,因为这通常会导致比替代方案更好的性能。
  • 正如我所提到的,我自己不会使用 int 来存储数据。我会使用我需要的宽度。我将 int 用于计数器之类的东西,通常它是在寄存器上创建的,甚至从未移动到缓存或内存中。
  • @DavidHeffernan 是的。我可能措辞不佳,但意图是暗示“自然大小”有点模糊,可以解释。从历史上看,人们可能会将其解释为寄存器大小(但即便如此:int 在某些具有 32 位寄存器但具有 16 位内存接口的摩托罗拉 68000 上是 16 位)。今天,虽然这仍然是最明显的解释,但还有许多其他方面需要考虑。
  • @user2341104 形式上,您不能在可移植代码中使用精确大小的类型,因为它们并非无处不在。实际上,这也可能不是一个好主意,因为它会导致代码更难阅读且更脆弱。
  • @JamesKanze - 我不关心异国架构,我认为对于 x86/x64 和 ARM7 我是安全的,对吧?
【解决方案2】:

The Open Group 在http://www.unix.org/whitepapers/64bit.html 解释了历史、权衡和决策。它涵盖了各种数据模型、它们的优缺点以及为适应 64 位计算而对 Unix 规范所做的更改。

【讨论】:

    【解决方案3】:

    ints 在大多数主要架构上一直是 32 位,以至于将它们更改为 64 位可能会导致比它解决的问题更多的问题。

    【讨论】:

    • 什么样的问题?我经历了int 从 16 位到 32 位的迁移,没有引起任何问题。我看不出将 int 从 32 位更改为 64 位会导致任何问题。
    • 功能上应该没有问题,但在性能方面,64 位整数的后果可能很重要。特别是,显着影响整数数组或包含它们的对象与内存层次结构交互的方式。值得注意的是,从 16 位到 32 位的转换也存在同样的论点。
    • @James 在程序员明确假设 int 是 32 位之前是正确的。很多代码都基于这个假设。
    • @JamesKanze 正如其他人所指出的那样,只是假设 32 位 int 的遗留代码量太大了。一些小众领域可能不受此假设的影响(例如非主流 CPU 架构、嵌入式系统等),但对于主流计算机系统而言,破坏现有代码库的大部分影响是不容忽视的。
    • @rwong 有多少代码真的取决于int 正好是 32 位?在大多数情况下,我认为代码是无关紧要的,只要 int 可以包含所需的所有值。
    【解决方案4】:

    因为对于很多软件来说,拥有 64 位整数并没有什么优势。

    使用 64 位 int 来计算可以用 32 位整数计算的东西(对于许多目的,高达 40 亿(或 +/- 2 亿)的值就足够了),并且将它们变大不会帮助任何事情。

    但是,使用更大的整数会对处理器缓存中容纳多少整数大小的“事物”产生负面影响。因此,将它们变大将使涉及大量整数(例如数组)的计算花费更长的时间,因为。

    int 是机器字的自然大小,不是 C++ 标准规定的。在大多数机器使用 16 位或 32 位的时代,将其设为 16 位或 32 位是有意义的,因为这对于这些机器来说是一个非常有效的大小。对于 64 位机器,这不再“有帮助”。因此,使用 32 位 int 更有意义。

    编辑: 有趣的是,当微软转向 64 位时,他们甚至没有将 long 设为 64 位,因为它会破坏太多依赖 long 是 32 位值的东西(或者更重要的是,他们有一个一堆依赖 long 在他们的 API 中作为 32 位值的东西,有时客户端软件使用 int 有时使用 long,他们不希望它破坏)。

    【讨论】:

    • 从技术上讲,微软的界面中从来没有long。他们确实有DWORD,毫无疑问是32位。但是有很多代码错误地假设long==DWORD==32 bits
    • int 是机器字的自然大小不是 C++ 标准规定的”:第 3.9.2 节呢?
    • 在阅读了 3.9 的大部分内容后,我找到了这样的部分:“Plain ints have the natural size of the architecture of the execution environment”,我想这可以解释为“a机器字”,但在支持 16、32 和 64 位整数(例如 x86-64)且速度/效率通常相同的机器中,我很确定编译器供应商可以选择这样的大小。跨度>
    • @MSalters:不,他们有一个“LONG”,即typedef'd 为long int
    • @MatsPetersson:正确,但这只是一个细节。 unsigned long==DWORD==32 bitslong==LONG==32 bits 都是错误的假设,原因相同:使用的 C 类型是实现细节,Windows SDK 类型的宽度是有保证的。
    【解决方案5】:

    主要原因是向后兼容。此外,已经有一个 64 位整数类型 long 和浮点类型:floatdouble。为不同的架构改变这些基本类型的大小只会引入复杂性。此外,32 位整数在范围方面满足了许多需求。

    【讨论】:

    • 哦。那么为什么int 仍然不是 16 位呢?
    • 它将如何引入不存在的复杂性?你不能指望int 的大小,而且我知道它是 16、36 或 48 位而不是 32 位的平台。
    • @David Heffernan,因为它太小了
    • @thomas 同理,你也可以说 64 太大了。换句话说,compat 不是驱动程序。
    • @James Kanze,有很多程序(尽管设计得很糟糕)取决于 int 大小要小(不是特别是 32 位),例如一些压缩算法
    【解决方案6】:

    我最初写这篇文章是为了回复this question。虽然我已经对其进行了一些修改,但基本相同。

    首先,可以使用宽于 32 位的普通整数,正如 C++ draft 所说:

     注意:普通整数旨在具有执行环境架构建议的自然大小;提供其他有符号整数类型以满足特殊需要。 — 尾注

    强调我的

    这表面上似乎是说在我的 64 位架构(以及其他所有人的架构)上,一个普通的 int 应该有 64 位大小;这是架构建议的大小,对吗?但是我必须断言,即使是 64 位架构,自然 的大小 32 位。规范中的引用主要用于需要 16 位纯整数的情况——这是规范允许的最小大小。

    最大的因素是约定,从具有 32 位纯 int 的 32 位架构开始,如果您将其保留为 32 位,则将源代码调整为 64 位架构会更容易,对于设计人员和他们的用户来说都是两个不同的方式:

    首先,系统之间的差异越小,每个人就越容易。系统之间的差异只是让大多数程序员头疼的问题:它们只会使跨系统运行代码变得更加困难。它甚至会增加相对罕见的情况,即您无法在具有相同分布的仅 32 位和 64 位的计算机上执行此操作。然而,正如 John Kugelman 所指出的,架构已经从 16 位普通 int 变为 32 位普通 int,今天可以再次经历这样做的麻烦,这与他的下一点有关:

    更重要的部分是它会导致整数大小或需要新类型的差距。因为sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) 在实际规范中,所以如果将普通 int 移动到 64 位,则会强制出现间隙。它从转移long 开始。如果将普通 int 调整为 64 位,则 sizeof(int) <= sizeof(long) 的约束将强制 long 至少为 64 位,并且从那里存在大小的内在差距。由于long 或普通 int 通常用作 32 位整数,而现在它们都不能,所以我们只有一种可以使用的数据类型,short。因为short 至少有 16 位,如果您简单地丢弃该大小,它可能会变成 32 位并在理论上填补该空白,但是 short 旨在针对空间进行优化,因此应该保留像这样,也有小、16 位整数的用例。无论您如何安排尺寸,都会损失宽度,因此 int 的用例完全不可用。更大的宽度并不一定意味着它更好。

    现在这意味着需要更改规格,但即使设计师失职,也很可能会因更改而损坏或过时。持久系统的设计人员必须使用整个交织代码库,包括他们自己在系统中的代码、依赖项和他们想要运行的用户代码,并且在不考虑后果的情况下进行大量工作是不明智的.

    附带说明,如果您的应用程序与 >32 位整数不兼容,您可以使用static_assert(sizeof(int) * CHAR_BIT <= 32, "Int wider than 32 bits!");。但是,谁知道规范发生变化,64位纯整数将被实现,所以如果你想成为未来的证明,不要做静态断言。

    【讨论】:

      【解决方案7】:

      C++标准并没有说int类型应该使用多少内存,而是告诉你int类型至少应该使用多少内存。在许多 32 位指针变量的编程环境中,“int”和“long”都是 32 位长。

      【讨论】:

      • 在许多其他环境中,它们不是。 (在我目前工作的所有环境中,指针都是 64 位的。在我过去工作的很多环境中,int 是 16 位。)
      【解决方案8】:

      因为还没有人指出这一点。

      int 保证在 -32767 到 32767(2^16) 之间,这是标准要求的。如果你想在所有平台上支持 64 位数字,我建议使用正确的类型 long long,它支持(-9223372036854775807 到 9223372036854775807)。

      int 可以是任何东西,只要它提供标准要求的最小范围。

      【讨论】:

      • 2^16 现在似乎太少了,不实用,考虑到可能所有的实现都已经做到了,也许标准需要升级到 32 位 int。但话又说回来,这可能会给旧代码带来问题。
      • @user2341104 我认为嵌入式环境中使用的 16 位处理器仍然很多。
      • long long?你不是说int64_t吗?
      • @DavidHeffernan 我可能正在查看旧标准并在此处查看旧答案。但我对它们之间的区别有点无知:(。
      • @DavidHeffernan:不。int64_t 是可选的,long long 不是。
      猜你喜欢
      • 2017-01-21
      • 2018-08-04
      • 1970-01-01
      • 2011-11-08
      • 2012-10-22
      • 1970-01-01
      • 2011-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多