【问题标题】:How can <stdint.h> types guarantee bit width?<stdint.h> 类型如何保证位宽?
【发布时间】:2019-11-02 01:45:47
【问题描述】:

由于 C 是一种松散类型的语言,而 stdint.h 只定义了 typedefs(我假设),如何保证 int 的宽度?

我要问的是关于实现而不是库的使用。

【问题讨论】:

    标签: c linker compiler-construction


    【解决方案1】:

    &lt;stdint.h&gt; 类型如何保证位宽?

    C 不能,C 不需要它。

    C 确实需要 最小 宽度。


    只有在支持它们的系统上才需要以下个性化,符号类型没有填充和 2 的补码。

    (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t
    

    实现可以选择具有其他大小,例如 uint24_t

    以下为必填项。

    (u)int_least8_t, (u)int_least16_t, (u)int_least32_t, (u)int_least64_t
    

    【讨论】:

      【解决方案2】:

      stdint.h 是 C 实现的一部分,它使用适合该实现的任何底层类型定义 typedefs。。它不是一个可以携带到任何你喜欢的 C 实现的可移植文件。

      【讨论】:

      • 因此编译器应该将它们理解为诸如 int 之类的本机类型,特别是对于那些具有魔力的类型。对吗?
      • @nikoss,我不知道你所说的魔法是什么意思。重点是编译器是决定诸如int(在规范规定的范围内)等类型的实际宽度的人,因此编译器能够提供合适的stdint.h
      • 而且,如果类型是在an ABI中约定的,那么它甚至不需要由编译器提供;库和/或标头实现可以是独立的,并且仍然具有正确的类型,因为它们已在 ABI 中列出。
      • 当我说编译器时,我真的是指编译器编写者。是的,他们的决定可能在很大程度上受到架构和/或操作系统 ABI 等其他因素的影响。
      • @ikegami:我并不是要反对你所说的;我只是发现它是一个常见的混淆源(参见最近的“'实现'是什么意思?”问题),当常见系统具有来自不同方的编译器、链接器、内核、std 库等时,这些边界在哪里?缺少理解的要素是他们都同意一些 ABI 合同。
      【解决方案3】:

      C 编译器最终需要编译为机器码。机器代码只有硬的、固定宽度的类型,如 32 位 int、64 位 int 等(或者更确切地说,它具有该大小的内存块 + 对该大小的内存进行操作并将其视为有符号或无符号)

      因此,创建编译器的人是在您向其请求int 时定义编译器实际使用的人,而stdint.h 头文件是他们编写的文件。它基本上是他们所做工作的文档。他们知道,例如他们的 long 类型是 64 位大小,所以添加一个 typedef long int64_t; 等。

      在int 是 16 位和 long 是 32 位的系统上,他们甚至可以让他们的编译器理解一个特殊的内部类型,例如将其命名为 __int64,然后使 stdint.h 包含 typedef __int64 int64_t;。

      C 标准只是定义必须有一个 stdint.h 标头随您的编译器一起提供,并且如果您在其中定义 int64_t,它必须映射到正确大小的数据类型。

      理论上可以将stdint.h 中的所有内容构建到编译器中(因此,与其使用__int64 之类的中间名称并将其类型定义为int64_t,不如直接使用@987654335 @ 直接,但是通过使用这种方法,在 stdint.h 之前编写的旧代码存在并定义了自己的名为 int64_t 的类型不能包含 stdint ,因此将继续编译。以两个下划线开头的名称历来保留用于编译器制造商,因此现有的 C 代码不可能使用名称 __int64。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-07
        • 1970-01-01
        • 2021-12-09
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        • 2020-10-26
        相关资源
        最近更新 更多