【问题标题】:Size of int in C on different architectures不同架构上 C 中 int 的大小
【发布时间】:2010-12-09 08:44:06
【问题描述】:

我知道 C 语言的规范并没有规定每个整数类型的确切大小(例如,int)。

我想知道的是:在 C(不是 C++)中有没有一种方法可以定义具有特定大小的整数类型,以确保它在不同的体系结构中是相同的?喜欢:

typedef int8 <an integer with 8 bits>
typedef int16 <an integer with 16 bits>

或任何其他允许程序的其他部分在不同架构上编译的方式。

【问题讨论】:

  • @zilgo:答案可能类似;问题不是。在 126279 中,OP 已经知道 stdint.h; NawaMan(显然)在问这个问题时不在。
  • 请注意,您的最后一个假设是错误的。 int 大小的差异不一定会阻止其他架构上的编译,但像i == i &amp; 0xFFFFFFFF 这样的潜在假设可能会。一个优秀的程序员在想要数学模 2^16 时会写 &amp; 0xFFFF,而不关心 unsigned short 是否正好有 16 位。
  • MSalters:当然。我不明白为什么这么多人似乎对固定宽度尺寸有着强烈的渴望 - 在 99% 的情况下,最小 宽度尺寸就是你所需要的。
  • 我正在将不同的数据打包到 char 数组(或 char 点)中,所以我需要处理大小。

标签: c cross-platform types integer


【解决方案1】:

C99 在stdint.h 中定义了int8_tint16_t 等类型。

【讨论】:

  • 我相信有一个版本涵盖了许多其他不符合 C99 的平台,但我不确定。
  • MSVC 不喜欢&lt;stdint.h&gt;。我不在乎,因为可怕的代码生成,我停止使用它。
  • 一个公共域(甚至不是 MIT/BSD 许可证——你甚至不需要保留版权归属)用于 MSVC 的 stdint.h(来自 MinGW 的稍微修改的版本):snipplr.com/view/18199/stdinth
  • @paxdiablo - int8_tint16_t 是可选的,但前提是实现实际上没有具有这些宽度的整数类型。
  • @paxdiablo:VC 根本不符合 C99。 (他们甚至没有声称是。)请参阅stackoverflow.com/questions/1156267 获取 VC 上的 stdint.h
【解决方案2】:

除非您使用#ifdef 左右检查每个平台,否则我怀疑这很容易实现。但是许多图书馆已经为您完成了这项任务。对于 MSVC,它是 __int8, __int16, &c. GTK 库有类似的 typedef。

【讨论】:

    【解决方案3】:

    据我所知,答案是否定的。我们为不同的平台编写代码,我们只使用#if/#else 为特定平台使用typedef。例如在 Win32 上:typedef int int32;

    【讨论】:

      【解决方案4】:

      不,C 标准规定了整数类型的最小尺寸,但不保证最大尺寸。

      如果该大小的类型可用,则实现应提供intN_t 类型。我只提到,由于您有一个跨平台标签 - 没有正确位宽类型的实现不需要提供这些类型。

      您通常可以选择(通过设置定义,例如cc -D_INT16_IS_INT#ifdefs)用于特定位大小的正确类型。您可以使用 CHAR_BITsizeof() 为您希望使用 C 代码支持的每个平台制定所需的定义。

      c1x 草案(n1362)的相关部分是:


      7.18.1.1 精确宽度整数类型

      1. typedef 名称intN_t 指定宽度为N、无填充位和二进制补码表示的有符号整数类型。因此,int8_t 表示宽度正好为 8 位的有符号整数类型。

      2. typedef 名称uintN_t 指定宽度为N 的无符号整数类型。因此,uint24_t 表示宽度正好为 24 位的无符号整数类型。

      3. 这些类型是可选的。但是,如果实现提供了宽度为 8、16、32 或 64 位的整数类型,没有填充位,并且(对于有符号类型)具有二进制补码表示,则它应定义相应的 typedef 名称。


      关于类型的选择,这样就足够了:

      #ifdef INT32_IS_SHORT
          typedef short INT32
      #endif
      #ifdef INT32_IS_INT
          typedef int INT32
      #endif
      #ifdef INT32_IS_LONG
          typedef long INT32
      #endif
      

      【讨论】:

      • 如果你想在系统没有精确大小时失败,那么只需使用int8_tint16_t - 如果系统没有它们,构建将失败 - 不需要对于条件代码。如果您不想失败,而是使用次佳类型,请使用 int_least8_t 或 int_least16_t。
      • 预处理器无法评估sizeof()
      • 根据 C99 标准,long 必须大于 16 位;)
      • 好点,乔,已修复,尽管我注意到了笑脸 :-) Michael,OP 希望“程序在不同的架构上编译”,所以编译失败可能还不够好,他们想要“特定尺寸”,因此可能也不需要下一个最佳类型。
      【解决方案5】:

      您想要的是&lt;stdint.h&gt;,符合C 标准(“C99”)的编译器将实现它。不幸的是,这不包括微软。幸运的是,一个开源项目为 Windows 提供了&lt;stdint.h&gt;,请参阅msinttypes

      这将允许您使用 int32_tuint32_t,以及 8、16 和 64 以及许多其他值。

      注意:头文件本身在标准中不是可选的,但是,头文件中的大多数类型都是单独可选的。有些不是。最常用的类型是可选类型,但没有什么能阻止您使用必需的类型。问题是,如果一个实现提供了头文件,实际上他们定义了所有的类型。

      【讨论】:

      • 这是否意味着如果我总是用 C99 编译器编译我的代码并且总是包含 ,我应该确保 int32_t 总是 4 个字节?
      • @NawaMan - 您可以确定 int32_t 将具有 32 位。如果平台没有 32 位 int 类型,则编译将失败,因为不会定义 int32_t 类型。此外,许多非 C99 编译器提供 stdint.h - 对于那些不提供的(Microsoft),您可以从其他 cmets/answers 中指出的几个地方获得一个,包括:snipplr.com/view/18199/stdinth
      • @NawaMan:是的。还应该注意的是,C99 为您提供了经典类型的最小值:int >= 16, long >= 32, long long >= 64。
      【解决方案6】:

      您总是可以编写一个使用无符号字符向量作为数字的算术库。这样你就可以使用你想要的任何位长的数字,甚至允许位长变化。

      实际上,您不需要实现这样的库,因为 GNU MP 已经处理了。

      http://gmplib.org/

      【讨论】:

        【解决方案7】:

        您可能想看看pstdint.h。它是 stdint.h 的可移植实现,不需要 C99 编译器支持。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-14
          • 1970-01-01
          • 2021-10-11
          • 1970-01-01
          • 2020-11-10
          • 2017-06-01
          相关资源
          最近更新 更多