C 架构/ABI,其中sizeof(long)!=8.

C 架构/ABI,其中sizeof(long)!=8.,c,abi,C,Abi,在x86/amd64世界中,sizeof(long-long)是8 让我引用一位颇有见地的8岁孩子的话: 斯科特·罗伯特·拉德写道: 在64位AMD64体系结构上,GCC将long定义为64位 与长的相同 假设某些64位指令(乘法)产生128位 结果,long被定义为128位,这似乎合乎逻辑吗 不,有两个原因: 64位“long”选项已写入的ABI中 大多数LP64型操作系统;我们不能单方面改变它 这实际上是正确的选择,因为它消除了畸变 这使得“long”不是最广泛的基本整数类型。有 在野外编写

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

让我引用一位颇有见地的8岁孩子的话:

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

在64位AMD64体系结构上,GCC将
long
定义为64位 与长的相同

假设某些64位指令(乘法)产生128位 结果,
long
被定义为128位,这似乎合乎逻辑吗

不,有两个原因:

  • 64位“
    long
    ”选项已写入的ABI中 大多数LP64型操作系统;我们不能单方面改变它

  • 这实际上是正确的选择,因为它消除了畸变 这使得“
    long
    ”不是最广泛的基本整数类型。有 在野外编写了大量的代码,假设
    sizeof(long)>=sizeof(size\u t)
    -这至少是潜在的 被ABIs打破,long比long宽

    (这是一个在发展过程中极具争议的话题 C99.从外部角度看,我能说得最好的是,
    long
    ' 仅仅是因为微软的压力才被标准化的,而微软却不能支持 出于某种原因,我们实施了LP64模型。其他人都不喜欢这个想法 使“
    长”
    ”不一定是最宽的基本整数类型。)

  • 目前的最佳实践似乎是提供“扩展积分” 键入“
    \uuu int128
    ”。这不存在“
    long
    ”的问题,因为 它不是一个基本的整数类型(特别是,它不能用于
    size\u t

    zw


    long-long
    是最宽的基本整型。在我所知道的任何非死旧体系结构/ABI上,它都是64位长的。这允许使用简单的跨平台(至少对于许多32/64位体系结构)TypeDef:

    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++支持<代码> %LLD <代码> %LLU</代码>仅2005)
    但是这个解决方案的可移植性可以通过对以下问题的回答来表达


    什么是体系结构/ABIs,其中
    sizeof(long-long)!=8


    如果您不能提供任何最新/最新版本,请继续使用旧版本,但前提是它们仍在使用。

    TI TMS320C55x体系结构的字符位为16位,长为40位。虽然40位
    long-long
    违反了ISO,但
    sizeof(long-long)
    与8不同

    实际上,几乎所有具有
    CHAR\u BIT>8
    的C99实现都具有
    sizeof(long-long)!=8

    TMS320C55x优化C/C++编译器用户指南(2003)

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

    #include <stdint.h>
    typedef int8_t s8;
    typedef uint8_t u8;
    typedef int16_t s16;
    ...
    
    #包括
    typedef int8_t s8;
    类型定义uint8_t u8;
    typedef int16_t s16;
    ...
    
    Heh。尽管这个问题明确要求
    sizeof(long-long)!=8
    ,我认为基于提问者真正想知道
    long
    的宽度不是64位的实现的动机。我想提问者可能已经在可移植性计划中确保了
    CHAR\u BIT==8
    ,例如要求Posix。@SteveJessop:你说得对。但是我在问题中没有提到它是为了得到更广泛的答案,也就是说,这里有更多的信息(因此很有趣)线程。应该将类型重命名为稍长的
    以避免ISO冲突。它不是使
    sizeof(long-long)==40/CHAR\u-BIT==2.5
    ?@ugoren实际上
    sizeof(long-long)==4
    在该体系结构中。剩下的24位是填充位。顺便说一句,
    typedef int s32
    在使用16位
    int
    的实现中失败,其中有一些微控制器正在运行。显然,这与
    long
    无关,这意味着你对
    s32
    的计划与你要问的问题无关:-),但我认为你更可能被
    s32
    绊倒,而不是
    s64
    @SteveJessop:当然。问题是关于
    long-long
    ,但出于通常目的,我只关心
    char
    short
    int
    分别为8、16和32位长的平台。假设
    sizeof(long)>=sizeof(size\t)
    真的很常见吗?我总是假设相反…@dreamlax:我不熟悉这场辩论,但我假设当时有代码将大小和偏移量存储在
    无符号long
    中。我不确定这实际上比Windows代码在
    int
    中存储的
    long
    要好多少,因为它阻止了MS实现LP64。但C89实际上保证了
    size\u t
    是一种“积分类型”,C89中的“积分类型”仅指标准中要求的基本类型。因此,C99允许
    size\u t
    unsigned long
    更大的类型是一个突破性的改变,因为C89禁止它。
    long
    不是微软的选择。它是标准化的,因为现有的实践以及在32位系统上需要64位类型,而流行的ABI已经将
    long
    作为32位。显然,您没有注意到引入这些typedef的要点。我很清楚
    intXX\t
    ,我甚至提到过他们。我的解决方案并不打算是“在任何地方都能工作”的解决方案(尽管这很好),而是“在大多数使用过的平台上都能工作”。但你的回答偏离了主题,参考了我的介绍,却没有回答实际的问题