【问题标题】:Architectures/ABIs where sizeof(long long) != 8sizeof(long long) != 8 的架构/ABI
【发布时间】:2012-07-15 12:19:22
【问题描述】:

在 x86/amd64 世界中,sizeof(long long) 是 8。

让我引用非常有见地的 8 岁 mail by Zack Weinberg

斯科特·罗伯特·拉德写道:

在 64 位 AMD64 架构上,GCC 将 long long 定义为 64 位,即 与long 相同。

鉴于某些 64 位指令(乘法)产生 128 位 结果,long long 被定义为 128 位看起来不合逻辑吗?

不,有两个原因:

  1. 64位'long long'的选择已写入ABI 大多数 LP64 型号的操作系统;我们不能单方面改变它。

  2. 这实际上是正确的选择,因为它消除了畸变 这使得 'long' 不是最广泛的基本整数类型。有 大量大量的代码写成假设 sizeof(long) >= sizeof(size_t) - 这至少是潜在的 被 long long 比 long 宽的 ABI 打破。

    (在开发过程中这是一个极具争议的话题 C99。据我所知,从外部角度来看,'long long' 只是在微软的压力下才标准化 出于某种原因实现了 LP64 模型。其他人都讨厌这个主意 'long' 不一定是最宽的基本整数类型。)

目前的最佳做法似乎是提供“扩展积分 type" __int128。这不存在 'long long' 的问题,因为 它不是 basic 整数类型(特别是,它不能用于 size_t)。

zw


long long 是最广泛的基本整数类型。在我知道的任何非死旧架构/ABI 上,它都是 64 位长的。这允许使用简单的跨平台(嗯,至少对于许多 32/64 位架构)类型定义:

typedef char               s8;
typedef unsigned char      u8;
typedef short              s16;
typedef unsigned short     u16;
typedef int                s32;
typedef unsigned int       u32;
typedef long long          s64;
typedef unsigned long long u64;

intXX_t 更好,因为:

  • 它们在不同平台上对 64 位整数使用相同的底层类型
  • 允许避免冗长的PRId64/PRIu64
    (我很清楚 Visual C++ 自 2005 年起才支持 %lld/%llu

但是这个解决方案的可移植性可以通过以下问题的答案来表达。


sizeof(long long) != 8 所在的架构/ABI 是什么?

如果您无法提供任何最近/现代的,那么请继续使用旧的,但前提是它们仍在使用中。

【问题讨论】:

  • 顺便说一句,typedef int s32 在 16 位 int 的实现上失败,其中有一些微控制器正在运行。显然这与long long 无关,这意味着您对s32 的计划与您提出的问题无关:-) 但我认为您更有可能绊倒s32 而不是s64 .
  • @SteveJessop:当然。问题仅与 long long 有关,但出于通常目的,我确实只关心 charshortint 分别为 8 位、16 位和 32 位长的平台。
  • 假设sizeof(long)>=sizeof(size_t) 真的很普遍吗?我一直认为相反...
  • @dreamlax:我不熟悉那场辩论,但我认为当时有代码将大小和偏移量存储在 unsigned long 中。我不确定这实际上是否比在int 中存储long 的Windows 代码更好,这阻止了MS 实现LP64。但实际上 C89 确实保证 size_t 是“整数类型”,而 C89 中的“整数类型”只是标准中要求的基本类型。因此,C99 允许 size_t 成为比 unsigned long 更大的类型是一个突破性的变化,因为 C89 禁止这样做。
  • long long 不是微软的选择。由于现有实践以及在流行的 ABI 已经将 long 作为 32 位的 32 位系统上需要 64 位类型,因此它被标准化。

标签: c abi


【解决方案1】:

TI TMS320C55x 架构具有 16 位的 CHAR_BIT 和 40 位的 long long。虽然 40 位的long long 违反了 ISO,但sizeof (long long) 与 8 不同。

实际上几乎所有带有CHAR_BIT > 8 的C99 实现都有sizeof (long long) != 8

TMS320C55x 优化 C/C++ 编译器用户指南 (2003) http://www.ti.com/lit/ug/spru281f/spru281f.pdf

【讨论】:

  • 嘿。尽管问题明确要求sizeof(long long) != 8,但我认为基于提问者真正想了解long long 宽度不是64 位的实现的动机。我想提问者可能已经在可移植性计划中确保了CHAR_BIT == 8,例如通过要求 Posix。
  • @SteveJessop:你是对的。但是我没有在问题中提到它以获得更广泛的答案,即在这里有更多信息(因此很有趣)的线程。
  • 应该重命名slightly longer类型以避免ISO冲突。
  • 不是sizeof(long long) == 40/CHAR_BIT == 2.5吗?
  • @ugoren 实际上是 sizeof (long long) == 4 在这个架构中。剩下的 24 位是填充位。
【解决方案2】:

您的“跨平台”类型定义只是被误导了。正确的是

#include <stdint.h>
typedef int8_t s8;
typedef uint8_t u8;
typedef int16_t s16;
...

【讨论】:

  • 显然你错过了介绍这些类型定义的要点。我很清楚intXX_t,我什至提到了他们。我的解决方案不是“适用于任何地方”的解决方案(不过会很好),而是“适用于大多数使用过的平台”。 但是你没有回答主题,参考我的介绍,但没有回答实际问题。
  • 虽然它可能无法回答问题,但我相信我的回答解决了为什么您的问题的预期应用会被误导。考虑到我想用实际的 typedef 来说明它,我很难只发表评论。
  • 可怜的借口。您也可以在评论中说明它,例如写“typedef int8_t s8等”,大家就会清楚地理解你。
猜你喜欢
  • 2021-12-04
  • 2013-12-05
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
相关资源
最近更新 更多