【问题标题】:Does C99 mandate a `int64_t` type be available, always?C99 是否总是要求 `int64_t` 类型可用?
【发布时间】:2019-07-21 18:44:52
【问题描述】:

C99 标准是否要求符合标准的编译器定义(并且可用)64 位int64_t?或者它是可选的,并且恰好由所有流行的编译器定义?我显然是在专门询问 CPU 无法直接处理 64 位值的平台,但问题更笼统

我无法从C data types Wikipedia pagethis answer 中找到相关问题。

【问题讨论】:

  • 不确定 C99,但 int64_t 在 C11 中绝对是可选的,除非不是。有关详细信息,请参阅 C11 规范的第 7.20.1.1 节。
  • @user3386109:麻烦给个链接好吗?此外,您的措辞相当神秘。
  • 对不起,我没有链接。但是C11规范的草案网上是免费的,搜索N1570可以找到
  • Link to C11 draft。这些类型是可选的,但如果机器架构具有适当的类型,则应提供,如果某些整数类型具有相同的特征,则必须提供。
  • 无论如何,答案是“不”。你不能指望现有的类型。

标签: c 64-bit language-lawyer c99


【解决方案1】:

C99 标准是否要求符合标准的编译器具有 64 位 int64_t 定义(并且可用)?或者它是可选的,只是碰巧 被所有流行的编译器定义?

在某种意义上,该类型是可选的,在另一种意义上是有条件要求的。具体来说,C99 says

typedef 名称 intN_t 指定宽度为 N 的有符号整数类型 ,没有填充位和二进制补码表示。 [...]

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

因此,int64_t 是可选的,因为符合要求的实现不需要提供与int64_t 的特征完全匹配的任何类型,如果没有,则不需要(实际上,绝不能,根据另一部分)提供类型int64_t

C99 确实指定了 long long int 类型,其所需的最小范围需要至少 64 位宽的表示形式。现在有可能在某些实现中没有 正好 64 位宽的有符号整数类型(例如,int 可能是 24 位,long 48 和 long long 96),并且可能存在 64 值位整数类型,但它包含填充位或未以二进制补码表示。这样的实现可以完全符合但没有定义int64_t。但在实践中,目前还没有任何这样的通用实现。

【讨论】:

  • 那么你能有一个不提供int64_t的符合C99的编译器吗?我的意思是,可以说 long long 具有非 2 的幂大小或 128 位,而 int64_t 会丢失吗?
  • 是的,@einpoklum,原则上你可以。正如我所说,“一个符合要求的实现不需要提供任何与 int64_t 的特征完全匹配的类型,如果它不提供,那么它不需要(实际上,不能 [...])提供类型 int64_t ”。但是,在实践中,我不知道有任何现有的、符合 C99 或 C11 的实现未能提供 int64_t
【解决方案2】:

C99 标准是否要求符合标准的编译器定义(并且可用)64 位 int64_t?

不,但 C99 需要long long,它至少 64 位。

此外,int64_t 非常常见。没有int64_t,您不太可能遇到符合标准的 C99,因为几乎所有平台都需要

C11dr 7.20.1.1 精确宽度整数类型
(int64_t) .... 如果实现提供整数类型 宽度为 8、16、32 或 64 位,无填充位,并且(对于有符号类型)具有二进制补码表示,它应定义相应的 typedef 名称。

处理器的位宽不是此功能的一个因素 - long long 必须存在。如果 long long(或任何标准类型是 64 位 2 的补码),那么 int64_t 必须 也存在。处理器的位宽确实会影响性能


@R.. 注释强调了 long long 需要 64 位内存进行编码,按照规范只能支持 [-0x7fff-ffff-ffff-ffff ... +0x7fff-ffff-ffff 的范围-ffff],比 [-0x8000-0000-0000-0000 ... +0x7fff-ffff-ffff-ffff] 范围内的int64_t 差一倍。现在这样的平台非常罕见,如果它们存在的话。

【讨论】:

  • C 不要求 long long 为 64 位。 LLONG_MIN 被允许为 -0x7fffffffffffffff,如果实现做出如此糟糕的选择(并且,出于实际目的,63 位),这使得它比 64 位少了近 100 个 zeptobits。
  • @R.. 同意“C 不需要 long long 为 64 位。”,这就是为什么答案有“long long 至少是 64 位。”。它可以更广泛。它的范围可以窄到 [-0x7fff-ffff-ffff-ffff ... +0x7fff-ffff-ffff-ffff]
  • 它甚至不要求它是“至少 64 位”。它要求它至少为 63.999999999999999999921... 位。抱歉,我的第一条评论措辞有误,遗漏了“至少”这个短语,但关键是“至少”是错误的,因为允许补码、符号/大小和“有缺陷的补码”实现的向后规定。
  • @R.. 由于没有小数位这样的东西,这与“至少 64 位”是一样的。
  • @R.. 我的意思是你需要多少位来表示所需的范围。符号/幅度表示不能表示与 64 位二进制补码相同的范围,但它仍然需要 64 位来表示该范围(63 位幅度,1 位符号)。
【解决方案3】:

共有三组integer types

  • intN_t — 例如 int64_t 及其未签名的对应物;这些确切的类型可能不可用。
  • int_leastN_t——比如int_least64_tint_least8_tint_least16_tint_least32_tint_least64_t 类型及其无符号对应项是必需的 - 其他类型是可选的。
  • int_fastN_t——比如int_fast64_t;类型 int_fast8_tint_fast16_tint_fast32_tint_fast64_t 是必需的(它们是最快的类型,至少具有给定的宽度)。

该标准还要求支持long long,并且long long 的最小可接受范围需要至少64 位(请参阅§5.2.4.1 Sizes of integer types <limits.h>)。因此,该标准可以合法地要求支持 64 位或更多位的“最小”和“快速”类型——它还要求支持 long long

曾经有 36 位字的计算机,还有一些 60 位字的计算机。这两者都难以提供(基本上,“无法提供”)确切的宽度类型,但可以轻松地为“最小”和“快速”类型提供支持。

该标准不强制要求“精确宽度类型”——请参阅§7.20.1.1 Exact-width integer types ¶3

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

【讨论】:

  • There used to be computers with 36-bit words, and others with 60-bit words. 新标准应该忘记 40-50 岁的计算机。是的,他们不会有符合 C21 的编译器。一些标准的狂热分子会心脏病发作——将无法为铁氧体记忆机器编写可移植的代码。世界末日。生活将毫无意义。
  • 20 年前微弱相关的东西现在已经不那么相关了。 1999 年,至少有一些这类机器仍在计算机博物馆外运行。这些天来,没有那么多。
  • 另外,有 16 个 CHAR_BIT 的 DSP 类机器。他们有 int8_t 的问题,但其他类型没有问题。
  • 请注意,虽然int_least64_t 必须存在,但它的范围不必至少与int64_t 存在时一样大。 int_least64_t 只允许下降到 -2^63+1,而不是一直下降到 -2^63。这将在下一版 C 标准中修复。请参阅7.20.2.2 最小宽度整数类型的限制
  • @JonathanLeffler 没有人为他们编写可移植的代码。如果有人试图在他们身上使用 uint8_t,应该找一份更容易的工作
【解决方案4】:

不,C99 不强制要求 int64_t 类型。

(感谢@user3386109,@Clifford)

int64_t 类型不需要可用。引用C99 standard draft document N1256

7.18.11.1 精确宽度整数类型

  1. typedef 名称 int N_t 指定有符号整数类型等。 ...
  2. 这些类型是可选的。但是,如果实现提供了宽度为 ... 64 位的整数类型... 具有二进制补码 表示...它应该定义相应的 typedef 名称。

但请参阅 @chux 和 @JohnBollinger 对 long long 具有 64 位的回答。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2020-03-27
  • 1970-01-01
  • 2013-03-08
相关资源
最近更新 更多