据我了解,C规范说类型int
应该是目标平台上包含至少16位的最有效类型。
这不正是int_fast16_t
的C99定义吗?
也许他们只是为了保持一致,因为需要另一个int_fastXX_t
?
更新
总结下面的讨论:
示例: x86-64上的MSVC具有32位 int ,即使在64位系统上也是如此。 MS选择这样做是因为太多人认为 int 总是正好是32位,因此很多ABI会破坏。但是,如果x86-64上的64位值更快,则 int_fast32_t 可能是64位数。 (我认为实际情况并非如此,但它只是证明了这一点)
答案 0 :(得分:31)
int
在速度/大小方面是“最有效的类型” - 但不是根据C规范指定的。它必须是16位或更多位。
int_fast16_t
是速度最有效的类型,至少 16位int的范围。
示例:给定平台可能已经确定int
应该是32位,原因很多,而不仅仅是速度。对于16位整数,同一系统可能会发现不同的类型最快。
示例:在64位计算机中,人们希望将int
作为64位,编译器可以使用具有32位int
编译的模式来实现兼容性。在这种模式下,int_fast16_t
可以是64位,因为它本身是最快的宽度,可以避免对齐问题等。
答案 1 :(得分:24)
int_fast16_t
保证是最快的int,大小至少为16位。 int
除了以下内容外无法保证其大小:
sizeof(char) = 1 and sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).
它可以保持-32767到+32767的范围。
(7.20.1.3p2)“typedef名称
int_fastN_t
指定宽度至少为 N 的最快签名整数类型.typedef名称uint_fastN_t
指定最快无符号整数类型,宽度至少为 N 。“
答案 2 :(得分:7)
据我了解,C规范说类型
int
应该是目标平台上包含至少16位的最有效类型。
以下是int
标准实际所说的内容:(N1570 draft,第6.2.5节,第5段):
A&#34; plain&#34;
int
对象具有自然大小 执行环境的体系结构(足够大以包含任何INT_MIN
到INT_MAX
范围内的值,如 标题<limits.h>
)。
对INT_MIN
和INT_MAX
的引用可能有些误导;这些值是根据int
类型的特征选择的,而不是相反。
短语&#34; 自然尺寸&#34;也有点误导。根据目标架构,可能不会只有一个&#34;自然&#34;整数类型的大小。
在其他地方,标准规定INT_MIN
最多必须为-32767
,而INT_MAX
必须至少为+32767
,这意味着int
位于至少16位。
以下是关于int_fast16_t
(7.20.1.3)的标准:
以下每种类型都指定一个通常的整数类型 在所有至少具有的整数类型中运行最快 指定的宽度。
脚注:
不保证指定类型对所有目的都是最快的; 如果实施没有明确的理由选择一种类型 另外,它会简单地选择一些满足的整数类型 签名和宽度要求。
int
和int_fast16_t
的要求相似但不完全相同 - 而且它们同样含糊不清。
在实践中,int
的大小通常是根据&#34;自然大小&#34;以外的标准来选择的。 - 或者为了方便而解释该短语。通常选择新架构的int
大小来匹配现有架构的大小,以最小化移植代码的难度。并且有一个相当强烈的动机使int
不超过32位,因此类型char
,short
和int
可以涵盖8的大小, 16位和32位。在64位系统上,特别是x86-64,&#34; natural&#34;大小可能是64位,但大多数C编译器使int
32位而不是64位(有些编译器甚至只使long
为32位)。
我怀疑,int_fast16_t
的基础类型的选择较少依赖于这些考虑,因为任何使用它的代码都明确要求快速的16位有符号整数类型。许多现有代码对int
的特性做出了超出标准保证的假设,并且编译器开发人员必须满足这些代码,如果他们想要使用它们的编译器。
答案 3 :(得分:2)
不同之处在于,为了效率/优化目的, fast 类型允许更宽比其对应物(没有 fast )更宽。但是C标准并不能保证它们实际上更快。
C11,7.20.1.3最快的最小宽度整数类型
1以下每种类型都指定一个整数类型 通常最快262)在所有具有的整数类型中操作 至少是指定的宽度。
2 typedef名称int_fastN_t指定最快的有符号整数 宽度至少为N的类型.typedef名称为uint_fastN_t 指定宽度至少为最快的无符号整数类型 Ñ
262)不保证指定类型对所有人来说都是最快的 目的;如果实施没有明确的选择依据 一种类型而不是另一种类型,它只会选择一些整数类型 满足签名和宽度要求。
另一个区别是 fast 和 less 类型是必需类型,而其他确切的宽度类型是可选:
3需要以下类型:int_fast8_t int_fast16_t int_fast32_t int_fast64_t uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t此表单的所有其他类型都是可选的。
答案 4 :(得分:2)
从C99基本原理7.8
整数类型的格式转换<inttypes.h>
(标准附带的文档),强调我的:
C89指定该语言应支持四个签名和 无符号整数数据类型,
char
,short
,int
和long
,但地点 除了int
和short
之外,对其大小的要求非常低 至少16位且long
至少与int
一样长且不小 超过32位。对于16位系统,大多数实现分配8,16, 分别为char
,short
,int
和long
的16位和32位。对于32位 系统,通常的做法是分配8,16,32和32位 这些类型。int
大小的这种差异可能会产生一些问题 从一个系统迁移到另一个系统的用户分配不同的用户 size到整数类型,因为标准C的整数提升规则 可以意外地产生无声的变化。需要定义一个 随着64位的引入,扩展整数类型增加 系统
<inttypes.h>
的目的是提供一组整数类型 定义在整个机器上是一致的,并且独立于 操作系统和其他实现特性。它定义, 通过typedef
,各种大小的整数类型。实施是免费的 将它们作为标准C整数类型或扩展名typedef
支持。一致使用此标头将大大增加 跨平台的用户程序的可移植性。
int
和int_fast16_t
之间的主要区别在于后者很可能没有这些“实现特性”。您可能会将其视为:
我不关心int
大小的当前操作系统/实施“政治”。只要给我一个最快签名的整数类型,至少16位是。
答案 5 :(得分:1)
在某些平台上,使用16位值可能比使用32位值 更慢[例如]一个8位或16位存储器需要执行32位加载,修改加载的值,并写回结果]。即使一个高速缓存中的16位值与32位值一样多(正常情况下16位值比32位系统上的32位值快),也需要每次写入在读取之前会否定可能产生的任何速度优势,除非数据结构的读取频率远远高于写入数据结构。在这样的平台上,类似int_fast16_t
的类型可能是32位。
话虽如此,标准不会遗憾地允许编译器最有用的语义,这将允许类型为int_fast16_t
的变量,其地址不会被任意地表现为16位类型或更大的类型,取决于方便的。例如,考虑一下方法:
int32_t blah(int32_t x)
{
int_fast16_t y = x;
return y;
}
在许多平台上,存储在存储器中的16位整数通常可以像存储在寄存器中的那些一样进行操作,但是没有指令可以对寄存器执行16位操作。如果存储在内存中的int_fast16_t
变量只能保存-32768到+32767,则同样的限制将适用于存储在寄存器中的int_fast16_t
变量。由于将过大的值强制转换为过小的有符号整数类型而无法保存它们是实现定义的行为,这将强制上述代码在返回之前添加指令以对x
的低16位进行符号扩展;如果标准允许这种类型,灵活的“至少16位,但更方便”类型可以消除对此类指令的需要。
答案 6 :(得分:1)
两种类型如何不同的示例:假设存在一种架构,其中8位,16位,32位和64位算术同样快。 (i386接近。)然后,实现者可能使用LLP64模型,或者更好,但允许程序员在ILP64,LP64和LLP64之间进行选择,因为那里有很多代码假定long是32位,并且sizeof(int) <= sizeof(void*) <= sizeof(long)
。任何64位实现都必须至少违反其中一个假设。
在这种情况下,int
可能是32位宽,因为这将破坏来自其他系统的最少代码,但uint_fast16_t
仍然可以是16位宽,节省空间。