【问题标题】:Is int ever needed on x64?x64上是否需要int?
【发布时间】:2010-09-25 05:54:46
【问题描述】:

如前所述,针对 x64 的 C 代码应始终使用 size_t 而不是 int 来表示计数和数组索引等内容。

鉴于此,将 size_t(typedef'd 更短)标准化而不是 int 作为整个代码库中通常的整数类型,可以说会更简单,更不容易出错。

我有什么遗漏吗?假设您不需要有符号整数,并且您没有存储小整数的大型数组(将它们设为 32 位而不是 64 位可以节省内存),是否有任何理由使用 int 而不是 size_t?

【问题讨论】:

  • 嗯,什么? “假设你不需要有符号整数”?我有没有曾经参与过一个没有做过的项目??
  • 嘿,很公平,我猜是不同的经历;有符号整数可以从语言中完全删除,我不会错过它们。好的,让我们改为 除非您需要有符号整数
  • @rwa 这真的取决于,认为 int 是万事通。
  • 假设你不需要 int 类型存在的东西(有符号字长整数),那么,ugh,不需要
  • @rwallace:奇怪的是,我更赞成从所有语言中删除无符号整数类型。

标签: c 64-bit


【解决方案1】:

相反,我更喜欢固定整数大小的东西,uint8_t ...uint64_t(很快就会有unit128_t),这些将是基本类型。所以你会知道你得到了什么。

和其他 typedefsize_t 然后别名为这些。然后,您可以简单地检查 typedef 中的 uintprt_t 并推断您的地址宽度,例如

而且,人们肯定需要签名类型。 但这种关系当然可以澄清。现在已经在标准中,有符号类型是从无符号类型推导出来的。这可以通过强制使用前缀signed 来明确说明。但可以肯定的是后者不会发生,人们对int的感情太深了:)

【讨论】:

    【解决方案2】:

    正如 Eli 所说,int 通常(不总是)是字长,即在内存和 CPU 中移动对象的首选单位。因此,即使您忽略内存使用,您仍然可以获得更好的性能。

    因此,当您不需要大于 +/- (2^15 - 1) 的范围或特定宽度时,我认为使用 long 作为“常规”有符号整数类型是非常合理的。

    【讨论】:

    • 按照正常用法,x86 上的字长为 64 位;但实际上 int 始终为 32 位以实现向后兼容性。从什么意义上说,x86 的字长为 32 位?哪些操作在 32 位中效率更高?
    • @rwallace,这当然不是真的。 ILP64 和 SILP64 都已实现,它们都有 64 位整数。我没有资格深入谈论 x86 性能。但我认为 32 位值在 x86_64 上的性能不会更差。所以我所说的一般(不适用于任何特定架构)规则仍然适用。
    • 正确,不合格的 always 是错误的术语;我的意思是 int=32 bits 是主流,如果你运行例如Windows 下的 Microsoft C++ 或 Linux 下的 GCC,无论 CPU 如何,您都将获得 32 位 int。在某些情况下,32 位在 x64 上的性能更差,例如因为在用作偏移量之前需要扩展到 64 位。难题似乎是 32 位是否有更好的性能。
    • @rwallace, @Matthew: 如果有一天你想拥有标准类型的 5 种不同宽度 (8,...,128) 的整数类型,int 将被固定为 32有点,没有太多选择。
    【解决方案3】:

    使用size_t“用于计数”并作为通用无符号整数类型几乎总是一个设计错误。 size_t 只够容纳平台支持的最大连续对象的大小。这立即意味着它可以相当合理地用作对象中字节的计数或数组中元素的计数(或索引)(因为数组始终是连续物体)。但是一旦我们摆脱了连续性要求,size_t 就不再起作用了。您不能有意义地使用size_t 来计算链表中的元素,因为在一般情况下size_t 的范围是不够的。

    当然,将size_t 用于此类目的也是错误的在概念上size_t 实现了对象 size 的概念,而不是对象 count 的概念。使用size_t 进行数组索引仅适用于抽象数组。使用size_t 来索引具体的应用程序特定的数组是很奇怪的。

    我个人更喜欢使用 unsigned 进行计数和数组索引(除非我为此目的有更具体的类型),前提是该类型的范围在我的应用程序的域中是足够的。

    【讨论】:

    • size_t 也比 unsigned 更适合计数。查看callocfreadfwrite 的参数。当然可能有一些 病态 架构,其中 size_t 小于对象的实际最大数量(例如,在链表中),因为内存分割或其他类似的丑陋,但是有很多 真正的架构,其中unsigned 远小于对象的最大数量 - 基本上是运行任何 Unix 的任何 64 位机器,以及 Windows。
    • @R..:特定于应用程序的容器中对象的最大数量由应用程序域决定,而不是由架构决定。我明确表示,只有当unsigned 的范围在我的应用程序域内足够时,我才会使用它。 size_t 从不适合该目的,无论其范围如何,因为它实现的概念不是正确的。这就像使用一个指定温度的类型来计算篮子里的苹果,只是因为它的范围恰好“足够大”。
    • @R..:我不清楚这里对callocfwrite 的引用是什么。所有这些函数都适用于数组元素计数,而不适用于通用计数,我已经在我的回答中介绍了它。
    • @R..:至于“病态架构”……它们没有什么病态的。真正病态的是当前这一代程序员无法在平面内存模型之外进行思考。在任何情况下,如果有人因为总内存限制而想要使用“总是足够”的整数类型,那就是intptr_t\uintptr_t,而不是size_t。使用uintptr_t 在特定于应用程序域的代码中仍然是一个概念性错误,但至少它不像size_t 那样完全是一场灾难。
    • “size_t 仅足以容纳平台支持的最大连续对象的大小。”,在 C 中这反常地不一定正确。使用calloc,您可以分配大于size_t 可以表示的对象,如果您的系统支持它,我相信。关键是在C语言中,对象本身不具有任何类型,所以sizeof必须适用于它们的类型的逻辑在这里不适用。
    猜你喜欢
    • 2019-08-22
    • 2016-01-15
    • 2010-10-13
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多