【问题标题】:Why does Apple define UInt32 as long or int depending on platform?为什么Apple根据平台将UInt32定义为long或int?
【发布时间】:2014-05-06 19:15:44
【问题描述】:

我注意到 UInt32 的定义根据MacTypes.h 中的平台不同

#if __LP64__
typedef unsigned int                    UInt32;
typedef signed int                      SInt32;
#else
typedef unsigned long                   UInt32;
typedef signed long                     SInt32;
#endif

如果unsigned int 在 32 位和 64 位机器上总是 32 位,他们为什么还要有条件地检查平台?

【问题讨论】:

  • 类似问题:NSInteger 在 32 位模式下是 int,在 64 位模式下是 long。如果 Apple 通常将 NSInteger 定义为 long,那么我们就不必为每个 printf 语句添加强制转换。
  • 或许else案例也支持16位系统int

标签: c macos-carbon


【解决方案1】:

UInt32 类型在 64 位支持之前存在。它在历史上被定义为unsigned long。可能是unsigned int。我不知道当时为什么选择long 而不是int。这种选择在很大程度上是武断的。

不过,一旦做出选择,就无法更改,即使 unsigned int 可以同时用于 32 位和 64 位。

如果它被改变,最重要的就是 C++。在 C++ 中,参数类型被烘焙到目标文件和库中的符号名称中。 longint 是不同的类型,所以 void foo(long);void foo(int); 是具有不同符号名称的独立函数。如果 UInt32 更改为 32 位,那么您将无法链接到使用旧定义构建的库。如果使用新定义重新构建库,则旧的编译代码将无法加载它们。

【讨论】:

    【解决方案2】:

    我的猜测是它最初是一些旧代码:

    typedef unsigned long                   UInt32;
    typedef signed long                     SInt32;
    

    后来一位开发人员添加了 LP64,他通过添加以下行来做到这一点:

    #if __LP64__
    typedef unsigned int                    UInt32;
    typedef signed int                      SInt32;
    #else
    

    不影响以前的平台。

    当然,这样做没有多大意义。

    【讨论】:

      【解决方案3】:

      long 保证至少为 32 位。 int 在 16 位处理器上将是 16 位。这在http://en.wikipedia.org/wiki/C_data_types 等地方进行了讨论。

      【讨论】:

      • 所有(当前)Apple 平台(OS X 和 iOS)在 32 位模式下使用 ILP32 数据模型,在 64 位模式下使用 LP64。所以在 "MacTypes.h" 的上下文中,int 总是 32 位,long 是 32 位或 64 位。
      • 所有当前平台,是的。 opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/… 但早在 1985 年(参见版权),还没有 32 位或 64 位 Mac。
      • (而且没有 iOS :-) - 这就是 typedef signed long SInt32 在“非 64 位模式”中的原因,这是有道理的。
      • 根据这个 (pastebin.com/nhey7Lw4) 和我见过的其他一些地方,MacOS 是 LP32,它有一个 16 位 int
      • @Peter for info Metrowerks CW for 68k Macintosh 支持 2 或 4 字节 int,默认为 4 字节。见faculty.petra.ac.id/indi/files/…
      【解决方案4】:

      整数类型的实际大小因实现而异。该标准仅要求数据类型之间的大小关系以及每种数据类型的最小大小。通常, sizeof(int) 反映了机器的“自然/原生”大小。在 64 位机器上,int 可能被定义为 32 或 64 位; 32 位架构上的 32 位,16 位机器上的 16 位。但是,标准表明 int 类型将始终至少为 16 位。

      【讨论】:

      • int 即使在 64 位机器上也通常是 32 位(可能是因为将 int 设为 64 位会使预定义的 8 位、16 位和 32 位整数类型变得困难)。该标准不仅“建议”int 至少为 16 位,而且绝对要求它。
      • @KeithThompson,你是绝对正确的。我会相应地调整答案。
      • 这仍然不能真正回答问题。由于int 在 32 位和 64 位平台上始终为 32 位(至少与 MacTypes.h 当前相关的平台),它可以UInt32 无条件定义为@987654327 @ 和 SInt32int。正如其他答案和 cmets 中所讨论的,显然原因是历史原因。
      【解决方案5】:

      unsigned int 总是 32 位长,这取决于型号

      • 在 LP64 模型中,long 和 pointer 是 64 位类型,int 是 32 位类型
      • 在 ILP64 模型中,int、long 和 pointer 是 64 位类型

      https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models

      在其他模型中,int 可以有任何其他位数。唯一的限制是它必须至少有 16 位

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-24
        • 1970-01-01
        • 2011-03-29
        • 1970-01-01
        • 2021-06-25
        • 2014-05-03
        • 2015-12-15
        • 1970-01-01
        相关资源
        最近更新 更多