As I understand it, the C specification says that type int
is supposed to be the most efficient type on target platform that contains at least 16 bits.
正如我所理解的,C规范说,类型int应该是目标平台上包含至少16位的最有效类型。
Isn't that exactly what the C99 definition of int_fast16_t
is too?
这不正是int_fast16_t的C99定义吗?
Maybe they put it in there just for consistency, since the other int_fastXX_t
are needed?
也许他们把它放在那里只是为了保持一致性,因为另一个int_fastXX_t是必需的?
Update
更新
To summarize discussion below:
总结讨论如下:
- My question was wrong in many ways. The C standard does not specify bitness for int. It gives a range [-32767,32767] that it must contain.
- 我的问题在很多方面都是错误的。C标准没有为int指定位,它给出了它必须包含的范围[-32767,32767]。
- I realize at first most people would say, "but that range implies at least 16-bits!" But C doesn't require two's-compliment (or even binary) storage of integers. If they had said "16-bit", there may be some platforms that have 1-bit parity, 1-bit sign, and 14-bit magnitude that would still being "meeting the standard", but not satisfy that range.
- 我最初意识到大多数人会说,“但是这个范围意味着至少16位!”但是C不需要两个(甚至二进制)的整数存储。如果他们说“16位”,可能会有一些平台有1位的奇偶性、1位的符号和14位的星等,它们仍然“符合标准”,但不满足这个范围。
- The standard does not say anything about int being the most efficient type. Aside from size requirements above, int can be decided by the compiler developer based on whatever criteria they deem most important. (speed, size, backward compatibility, etc)
- 标准并没有说int是最有效的类型。除了上面的大小需求,int可以由编译器开发人员根据他们认为最重要的标准来决定。(速度、大小、向后兼容性等)
- On the other hand, int_fast16_t is like providing a hint to the compiler that it should use a type that is optimum for performance, possibly at the expense of any other tradeoff.
- 另一方面,int_fast16_t就像给编译器提供了一个提示,它应该使用一种最适合性能的类型,可能是以牺牲其他任何代价为代价的。
- Likewise, int_least16_t would tell the compiler to use the smallest type that's >= 16-bits, even if it would be slower. Good for preserving space in large arrays and stuff.
- 同样,int_least16_t会告诉编译器使用最小的类型>= 16位,即使它比较慢。有利于在大数组中保存空间。
Example: MSVC on x86-64 has a 32-bit int, even on 64-bit systems. MS chose to do this because too many people assumed int would always be exactly 32-bits, and so a lot of ABIs would break. However, it's possible that int_fast32_t would be a 64-bit number if 64-bit values were faster on x86-64. (Which I don't think is actually the case, but it just demonstrates the point)
示例:x86-64上的MSVC具有32位int,甚至在64位系统上也是如此。MS选择这样做是因为太多的人认为int总是正好是32位的,所以很多ABIs会被破坏。但是,如果x86-64上的64位值更快的话,int_fast32_t可能是一个64位的数字。(我认为事实并非如此,但它只是证明了这一点)
7 个解决方案
#1
23
int_fast16_t
is guaranteed to be the fastest int with a size of at least 16 bits. int
has no guarantee of its size except that:
int_fast16_t保证是最快的int类型,大小至少为16位。int不能保证其大小,除非:
sizeof(char) = 1 and sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).
And that it can hold the range of -32767 to +32767.
它的取值范围是-32767到+32767。
(7.20.1.3p2) "The typedef name
int_fastN_t
designates the fastest signed integer type with a width of at least N. The typedef nameuint_fastN_t
designates the fastest unsigned integer type with a width of at least N."(7.20.1.3p2)" typedef name int_fastN_t指定了宽度至少为n的最快的带符号整数类型。typedef name uint_fastN_t指定了宽度至少为n的最快的无符号整数类型。"
#2
31
int
is a "most efficient type" in speed/size - but that is not specified by per the C spec. It must be 16 or more bits.
int类型在速度/大小上是“最有效的类型”——但这不是根据C规范来指定的。它必须是16位或更多位。
int_fast16_t
is most efficient type in speed with at least the range of a 16 bit int.
int_fast16_t是速度最快的类型,其范围至少为16位int。
Example: A given platform may have decided that int
should be 32-bit for many reasons, not only speed. The same system may find a different type is fastest for 16-bit integers.
示例:给定的平台可能已经决定int应该是32位的,原因有很多,而不仅仅是速度。同样的系统可能会发现不同类型的16位整数最快。
Example: In a 64-bit machine, where one would expect to have int
as 64-bit, a compiler may use a mode with 32-bit int
compilation for compatibility. In this mode, int_fast16_t
could be 64-bit as that is natively the fastest width for it avoids alignment issues, etc.
例如:在64位机器中,一个编译器可能会将int作为64位,编译器可能会使用32位整数编译的模式来兼容。在这种模式下,int_fast16_t可以是64位的,因为它可以避免对齐问题,等等。
#3
6
As I understand it, the C specification says that type
int
is supposed to be the most efficient type on target platform that contains at least 16 bits.正如我所理解的,C规范说,类型int应该是目标平台上包含至少16位的最有效类型。
Here's what the standard actually says about int
: (N1570 draft, section 6.2.5, paragraph 5):
以下是标准关于int: (N1570草案,第6.2.5节,第5段):
A "plain"
int
object has the natural size suggested by the architecture of the execution environment (large enough to contain any value in the rangeINT_MIN
toINT_MAX
as defined in the header<limits.h>
).“普通”int对象具有执行环境的体系结构所建议的自然大小(足够大,可以包含header
中定义的INT_MIN到INT_MAX之间的任何值)。
The reference to INT_MIN
and INT_MAX
is perhaps slightly misleading; those values are chosen based on the characteristics of type int
, not the other way around.
对INT_MIN和INT_MAX的引用可能有点误导;这些值是根据int类型的特征选择的,而不是相反。
And the phrase "the natural size" is also slightly misleading. Depending on the target architecture, there may not be just one "natural" size for an integer type.
“自然大小”这个词也有轻微的误导性。根据目标体系结构的不同,一个整数类型可能不只有一个“自然”大小。
Elsewhere, the standard says that INT_MIN
must be at most -32767
, and INT_MAX
must be at least +32767
, which implies that int
is at least 16 bits.
在其他地方,标准说INT_MIN至少必须是-32767,INT_MAX必须至少是+32767,这意味着int至少是16位。
Here's what the standard says about int_fast16_t
(7.20.1.3):
以下是标准对int_fast16_t(7.20.1.3)的说明:
Each of the following types designates an integer type that is usually fastest to operate with among all integer types that have at least the specified width.
下面的每个类型都指定了一个整数类型,该整数类型通常在所有具有至少指定宽度的整数类型中操作最快。
with a footnote:
补充说明:
The designated type is not guaranteed to be fastest for all purposes; if the implementation has no clear grounds for choosing one type over another, it will simply pick some integer type satisfying the signedness and width requirements.
指定的类型不能保证在所有用途上都是最快的;如果实现没有明确的理由选择一种类型而不是另一种类型,那么它将简单地选择满足签名和宽度要求的整数类型。
The requirements for int
and int_fast16_t
are similar but not identical -- and they're similarly vague.
int和int_fast16_t的需求是相似的,但并不相同——它们同样是模糊的。
In practice, the size of int
is often chosen based on criteria other than "the natural size" -- or that phrase is interpreted for convenience. Often the size of int
for a new architecture is chosen to match the size for an existing architecture, to minimize the difficulty of porting code. And there's a fairly strong motivation to make int
no wider than 32 bits, so that the types char
, short
, and int
can cover sizes of 8, 16, and 32 bits. On 64-bit systems, particularly x86-64, the "natural" size is probably 64 bits, but most C compilers make int
32 bits rather than 64 (and some compilers even make long
just 32 bits).
在实践中,int的大小通常是根据“自然大小”之外的标准来选择的——或者这个短语是为了方便而解释的。通常选择新体系结构的int大小来匹配现有体系结构的大小,以最小化移植代码的困难。并且有一个相当强烈的动机使int不超过32位,因此char、short和int类型可以涵盖8、16和32位的大小。在64位系统上,特别是x86-64,“自然”大小可能是64位,但是大多数C编译器都是32位而不是64位(有些编译器甚至只长32位)。
The choice of the underlying type for int_fast16_t
is, I suspect, less dependent on such considerations, since any code that uses it is explicitly asking for a fast 16-bit signed integer type. A lot of existing code makes assumptions about the characteristics of int
that go beyond what the standard guarantees, and compiler developers have to cater to such code if they want their compilers to be used.
我认为,int_fast16_t的底层类型的选择较少依赖于这些考虑,因为使用它的任何代码都显式地要求快速的16位有符号整数类型。许多现有的代码对int的特性做出了假设,这些特性超出了标准的保证,如果编译器开发人员希望使用他们的编译器,那么他们就必须迎合这些代码。
#4
2
The difference is that the fast types are allowed to be wider than their counterparts (without fast) for efficiency/optimization purposes. But the C standard by no means guarantees they are actually faster.
不同之处在于,为了提高效率/优化目的,允许快速类型比它们的对等类型更宽(没有快速)。但是C标准并不能保证它们实际上更快。
C11, 7.20.1.3 Fastest minimum-width integer types
最快的最小宽度整数类型
1 Each of the following types designates an integer type that is usually fastest 262) to operate with among all integer types that have at least the specified width.
下面的每个类型都指定了一个整数类型,该整数类型通常是最快的262),可以在所有具有至少指定宽度的整数类型中进行操作。
2 The typedef name int_fastN_t designates the fastest signed integer type with a width of at least N. The typedef name uint_fastN_t designates the fastest unsigned integer type with a width of at least N.
2 . typedef name int_fastN_t指定宽度至少为N的最快的带符号整数类型。typedef name uint_fastN_t指定宽度至少为N的最快的无符号整数类型。
262) The designated type is not guaranteed to be fastest for all purposes; if the implementation has no clear grounds for choosing one type over another, it will simply pick some integer type satisfying the signedness and width requirements.
262)指定的类型不能保证在所有用途上都是最快的;如果实现没有明确的理由选择一种类型而不是另一种类型,那么它将简单地选择满足签名和宽度要求的整数类型。
Another difference is that fast and least types are required types whereas other exact width types are optional:
另一个不同之处在于,快速和最少的类型是必需的类型,而其他确切的宽度类型是可选的:
3 The following types are required: int_fast8_t int_fast16_t int_fast32_t int_fast64_t uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t All other types of this form are optional.
需要以下类型:int_fast8_t int_fast16_t int_fast32_t int_fast64_t uint_fast_fast8_t uint_fast16_t uint_fast32_fast64_t所有其他类型的表单都是可选的。
#5
1
On some platforms, using 16-bit values may be much slower than using 32-bit values [e.g. an 8-bit or 16-bit store would require performing a 32-bit load, modifying the loaded value, and writing back the result]. Even if one could fit twice as many 16-bit values in a cache as 32-bit values (the normal situation where 16-bit values would be faster than 32-bit values on 32-bit systems), the need to have every write preceded by a read would negate any speed advantage that could produce unless a data structure was read far more often than it was written. On such platforms, a type like int_fast16_t
would likely be 32 bits.
在某些平台上,使用16位值可能比使用32位值要慢得多。一个8位或16位的存储将需要执行一个32位的加载,修改加载的值,并写回结果]。即使一个可以适合缓存中的16位值的两倍作为32位值(正常情况下16位值会比32位值在32位系统),需要每一个写之前读会否定任何可能产生的速度优势,除非一个数据结构是读比写更经常。在这种平台上,像int_fast16_t这样的类型可能是32位。
That having been said, the Standard does not unfortunately allow what would be the most helpful semantics for a compiler, which would be to allow variables of type int_fast16_t
whose address is not taken to arbitrarily behave as 16-bit types or larger types, depending upon what is convenient. Consider, for example, the method:
话虽如此,该标准不幸地不允许对编译器来说最有帮助的语义,即允许int_fast16_t类型的变量,其地址不被任意地作为16位类型或更大的类型,这取决于什么是方便的。例如,考虑方法:
int32_t blah(int32_t x)
{
int_fast16_t y = x;
return y;
}
On many platforms, 16-bit integers stored in memory can often be manipulated just as those stored in registers, but there are no instructions to perform 16-bit operations on registers. If an int_fast16_t
variable stored in memory are only capable of holding -32768 to +32767, that same restriction would apply to int_fast16_t
variables stored in registers. Since coercing oversized values into signed integer types too small to hold them is implementation-defined behavior, that would compel the above code to add instructions to sign-extend the lower 16 bits of x
before returning it; if the Standard allowed for such a type, a flexible "at least 16 bits, but more if convenient" type could eliminate the need for such instructions.
在许多平台上,存储在内存中的16位整数通常可以像存储在寄存器中的整数一样进行操作,但是没有在寄存器上执行16位操作的指令。如果存储在内存中的int_fast16_t变量只能保存-32768到+32767,那么同样的限制也适用于存储在寄存器中的int_fast16_t变量。由于将过大的值强制为太小而不能保存它们的带符号整型类型是实现定义的行为,这将迫使上面的代码在返回前添加指令以进行符号扩展;如果标准允许这种类型,一个灵活的“至少16位,如果方便的话”类型可以消除这种指令的需要。
#6
1
From the C99 rationale 7.8
Format conversion of integer types <inttypes.h>
(document that accompanies with Standard), emphasis mine:
从C99的基本原理7.8格式转换的整数类型
C89 specifies that the language should support four signed and unsigned integer data types,
char
,short
,int
andlong
, but places very little requirement on their size other than thatint
andshort
be at least 16 bits andlong
be at least as long asint
and not smaller than 32 bits. For 16-bit systems, most implementations assign 8, 16, 16 and 32 bits tochar
,short
,int
, andlong
, respectively. For 32-bit systems, the common practice is to assign 8, 16, 32 and 32 bits to these types. This difference inint
size can create some problems for users who migrate from one system to another which assigns different sizes to integer types, because Standard C’s integer promotion rule can produce silent changes unexpectedly. The need for defining an extended integer type increased with the introduction of 64-bit systems.C89指定语言应该支持四个签署和无符号整数数据类型,char,短,int和长,但地方很少要求他们大小以外,int和短至少16位和长至少只要int和不小于32位。对于16位系统,大多数实现分别将8、16、16和32位分配给char、short、int和long。对于32位系统,通常的做法是为这些类型分配8、16、32和32位。这种int大小的差异可能会给从一个系统迁移到另一个系统的用户带来一些问题,而这个系统会为整型类型分配不同的大小,因为标准C的整型提升规则会意外地产生无声的更改。定义扩展整数类型的需要随着64位系统的引入而增加。
The purpose of
<inttypes.h>
is to provide a set of integer types whose definitions are consistent across machines and independent of operating systems and other implementation idiosyncrasies. It defines, viatypedef
, integer types of various sizes. Implementations are free totypedef
them as Standard C integer types or extensions that they support. Consistent use of this header will greatly increase the portability of a user’s program across platforms.< inttypes的目的。h>提供了一组整数类型,它们的定义在不同的机器上是一致的,独立于操作系统和其他实现特性。它通过typedef定义各种大小的整数类型。实现可以*地将它们定义为它们所支持的标准C整数类型或扩展。一致地使用这个头将大大增加用户程序在跨平台上的可移植性。
The main difference between int
and int_fast16_t
is that the latter is likely to be free of these "implementation idiosyncrasies". You may think of it as something like:
int和int_fast16_t之间的主要区别是后者很可能没有这些“实现特性”。你可以这样想:
I don't care about current OS/implementation "politics" of int
size. Just give me whatever the fastest signed integer type with at least 16 bits is.
我不关心当前的操作系统/实现的int大小的“政治”。只要告诉我最快的带16位的整数类型。
#7
1
An example of how the two types might be different: suppose there’s an architecture where 8-bit, 16-bit, 32-bit and 64-bit arithmetic are equally fast. (The i386 comes close.) Then, the implementer might use a LLP64 model, or better yet allow the programmer to choose between ILP64, LP64 and LLP64, since there’s a lot of code out there that assumes long is exactly 32 bits, and that sizeof(int) <= sizeof(void*) <= sizeof(long)
. Any 64-bit implementation must violate at least one of these assumptions.
这两种类型可能不同的一个示例:假设有一个架构,其中8位、16位、32位和64位的算术都同样快。(i386接近。)然后,实现者可能会使用LLP64模型,或者更好的是让程序员在ILP64、LP64和LLP64之间进行选择,因为有很多代码假设long正好是32位,并且sizeof(int) <= sizeof(void*) <= sizeof(long)。任何64位的实现都必须至少违背其中一个假设。
In that case, int
would probably be 32 bits wide, because that will break the least code from other systems, but uint_fast16_t
could still be 16 bits wide, saving space.
在这种情况下,int可能是32位宽的,因为这会破坏其他系统中最少的代码,但是uint_fast16_t仍然可能是16位宽,节省空间。
#1
23
int_fast16_t
is guaranteed to be the fastest int with a size of at least 16 bits. int
has no guarantee of its size except that:
int_fast16_t保证是最快的int类型,大小至少为16位。int不能保证其大小,除非:
sizeof(char) = 1 and sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).
And that it can hold the range of -32767 to +32767.
它的取值范围是-32767到+32767。
(7.20.1.3p2) "The typedef name
int_fastN_t
designates the fastest signed integer type with a width of at least N. The typedef nameuint_fastN_t
designates the fastest unsigned integer type with a width of at least N."(7.20.1.3p2)" typedef name int_fastN_t指定了宽度至少为n的最快的带符号整数类型。typedef name uint_fastN_t指定了宽度至少为n的最快的无符号整数类型。"
#2
31
int
is a "most efficient type" in speed/size - but that is not specified by per the C spec. It must be 16 or more bits.
int类型在速度/大小上是“最有效的类型”——但这不是根据C规范来指定的。它必须是16位或更多位。
int_fast16_t
is most efficient type in speed with at least the range of a 16 bit int.
int_fast16_t是速度最快的类型,其范围至少为16位int。
Example: A given platform may have decided that int
should be 32-bit for many reasons, not only speed. The same system may find a different type is fastest for 16-bit integers.
示例:给定的平台可能已经决定int应该是32位的,原因有很多,而不仅仅是速度。同样的系统可能会发现不同类型的16位整数最快。
Example: In a 64-bit machine, where one would expect to have int
as 64-bit, a compiler may use a mode with 32-bit int
compilation for compatibility. In this mode, int_fast16_t
could be 64-bit as that is natively the fastest width for it avoids alignment issues, etc.
例如:在64位机器中,一个编译器可能会将int作为64位,编译器可能会使用32位整数编译的模式来兼容。在这种模式下,int_fast16_t可以是64位的,因为它可以避免对齐问题,等等。
#3
6
As I understand it, the C specification says that type
int
is supposed to be the most efficient type on target platform that contains at least 16 bits.正如我所理解的,C规范说,类型int应该是目标平台上包含至少16位的最有效类型。
Here's what the standard actually says about int
: (N1570 draft, section 6.2.5, paragraph 5):
以下是标准关于int: (N1570草案,第6.2.5节,第5段):
A "plain"
int
object has the natural size suggested by the architecture of the execution environment (large enough to contain any value in the rangeINT_MIN
toINT_MAX
as defined in the header<limits.h>
).“普通”int对象具有执行环境的体系结构所建议的自然大小(足够大,可以包含header
中定义的INT_MIN到INT_MAX之间的任何值)。
The reference to INT_MIN
and INT_MAX
is perhaps slightly misleading; those values are chosen based on the characteristics of type int
, not the other way around.
对INT_MIN和INT_MAX的引用可能有点误导;这些值是根据int类型的特征选择的,而不是相反。
And the phrase "the natural size" is also slightly misleading. Depending on the target architecture, there may not be just one "natural" size for an integer type.
“自然大小”这个词也有轻微的误导性。根据目标体系结构的不同,一个整数类型可能不只有一个“自然”大小。
Elsewhere, the standard says that INT_MIN
must be at most -32767
, and INT_MAX
must be at least +32767
, which implies that int
is at least 16 bits.
在其他地方,标准说INT_MIN至少必须是-32767,INT_MAX必须至少是+32767,这意味着int至少是16位。
Here's what the standard says about int_fast16_t
(7.20.1.3):
以下是标准对int_fast16_t(7.20.1.3)的说明:
Each of the following types designates an integer type that is usually fastest to operate with among all integer types that have at least the specified width.
下面的每个类型都指定了一个整数类型,该整数类型通常在所有具有至少指定宽度的整数类型中操作最快。
with a footnote:
补充说明:
The designated type is not guaranteed to be fastest for all purposes; if the implementation has no clear grounds for choosing one type over another, it will simply pick some integer type satisfying the signedness and width requirements.
指定的类型不能保证在所有用途上都是最快的;如果实现没有明确的理由选择一种类型而不是另一种类型,那么它将简单地选择满足签名和宽度要求的整数类型。
The requirements for int
and int_fast16_t
are similar but not identical -- and they're similarly vague.
int和int_fast16_t的需求是相似的,但并不相同——它们同样是模糊的。
In practice, the size of int
is often chosen based on criteria other than "the natural size" -- or that phrase is interpreted for convenience. Often the size of int
for a new architecture is chosen to match the size for an existing architecture, to minimize the difficulty of porting code. And there's a fairly strong motivation to make int
no wider than 32 bits, so that the types char
, short
, and int
can cover sizes of 8, 16, and 32 bits. On 64-bit systems, particularly x86-64, the "natural" size is probably 64 bits, but most C compilers make int
32 bits rather than 64 (and some compilers even make long
just 32 bits).
在实践中,int的大小通常是根据“自然大小”之外的标准来选择的——或者这个短语是为了方便而解释的。通常选择新体系结构的int大小来匹配现有体系结构的大小,以最小化移植代码的困难。并且有一个相当强烈的动机使int不超过32位,因此char、short和int类型可以涵盖8、16和32位的大小。在64位系统上,特别是x86-64,“自然”大小可能是64位,但是大多数C编译器都是32位而不是64位(有些编译器甚至只长32位)。
The choice of the underlying type for int_fast16_t
is, I suspect, less dependent on such considerations, since any code that uses it is explicitly asking for a fast 16-bit signed integer type. A lot of existing code makes assumptions about the characteristics of int
that go beyond what the standard guarantees, and compiler developers have to cater to such code if they want their compilers to be used.
我认为,int_fast16_t的底层类型的选择较少依赖于这些考虑,因为使用它的任何代码都显式地要求快速的16位有符号整数类型。许多现有的代码对int的特性做出了假设,这些特性超出了标准的保证,如果编译器开发人员希望使用他们的编译器,那么他们就必须迎合这些代码。
#4
2
The difference is that the fast types are allowed to be wider than their counterparts (without fast) for efficiency/optimization purposes. But the C standard by no means guarantees they are actually faster.
不同之处在于,为了提高效率/优化目的,允许快速类型比它们的对等类型更宽(没有快速)。但是C标准并不能保证它们实际上更快。
C11, 7.20.1.3 Fastest minimum-width integer types
最快的最小宽度整数类型
1 Each of the following types designates an integer type that is usually fastest 262) to operate with among all integer types that have at least the specified width.
下面的每个类型都指定了一个整数类型,该整数类型通常是最快的262),可以在所有具有至少指定宽度的整数类型中进行操作。
2 The typedef name int_fastN_t designates the fastest signed integer type with a width of at least N. The typedef name uint_fastN_t designates the fastest unsigned integer type with a width of at least N.
2 . typedef name int_fastN_t指定宽度至少为N的最快的带符号整数类型。typedef name uint_fastN_t指定宽度至少为N的最快的无符号整数类型。
262) The designated type is not guaranteed to be fastest for all purposes; if the implementation has no clear grounds for choosing one type over another, it will simply pick some integer type satisfying the signedness and width requirements.
262)指定的类型不能保证在所有用途上都是最快的;如果实现没有明确的理由选择一种类型而不是另一种类型,那么它将简单地选择满足签名和宽度要求的整数类型。
Another difference is that fast and least types are required types whereas other exact width types are optional:
另一个不同之处在于,快速和最少的类型是必需的类型,而其他确切的宽度类型是可选的:
3 The following types are required: int_fast8_t int_fast16_t int_fast32_t int_fast64_t uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t All other types of this form are optional.
需要以下类型:int_fast8_t int_fast16_t int_fast32_t int_fast64_t uint_fast_fast8_t uint_fast16_t uint_fast32_fast64_t所有其他类型的表单都是可选的。
#5
1
On some platforms, using 16-bit values may be much slower than using 32-bit values [e.g. an 8-bit or 16-bit store would require performing a 32-bit load, modifying the loaded value, and writing back the result]. Even if one could fit twice as many 16-bit values in a cache as 32-bit values (the normal situation where 16-bit values would be faster than 32-bit values on 32-bit systems), the need to have every write preceded by a read would negate any speed advantage that could produce unless a data structure was read far more often than it was written. On such platforms, a type like int_fast16_t
would likely be 32 bits.
在某些平台上,使用16位值可能比使用32位值要慢得多。一个8位或16位的存储将需要执行一个32位的加载,修改加载的值,并写回结果]。即使一个可以适合缓存中的16位值的两倍作为32位值(正常情况下16位值会比32位值在32位系统),需要每一个写之前读会否定任何可能产生的速度优势,除非一个数据结构是读比写更经常。在这种平台上,像int_fast16_t这样的类型可能是32位。
That having been said, the Standard does not unfortunately allow what would be the most helpful semantics for a compiler, which would be to allow variables of type int_fast16_t
whose address is not taken to arbitrarily behave as 16-bit types or larger types, depending upon what is convenient. Consider, for example, the method:
话虽如此,该标准不幸地不允许对编译器来说最有帮助的语义,即允许int_fast16_t类型的变量,其地址不被任意地作为16位类型或更大的类型,这取决于什么是方便的。例如,考虑方法:
int32_t blah(int32_t x)
{
int_fast16_t y = x;
return y;
}
On many platforms, 16-bit integers stored in memory can often be manipulated just as those stored in registers, but there are no instructions to perform 16-bit operations on registers. If an int_fast16_t
variable stored in memory are only capable of holding -32768 to +32767, that same restriction would apply to int_fast16_t
variables stored in registers. Since coercing oversized values into signed integer types too small to hold them is implementation-defined behavior, that would compel the above code to add instructions to sign-extend the lower 16 bits of x
before returning it; if the Standard allowed for such a type, a flexible "at least 16 bits, but more if convenient" type could eliminate the need for such instructions.
在许多平台上,存储在内存中的16位整数通常可以像存储在寄存器中的整数一样进行操作,但是没有在寄存器上执行16位操作的指令。如果存储在内存中的int_fast16_t变量只能保存-32768到+32767,那么同样的限制也适用于存储在寄存器中的int_fast16_t变量。由于将过大的值强制为太小而不能保存它们的带符号整型类型是实现定义的行为,这将迫使上面的代码在返回前添加指令以进行符号扩展;如果标准允许这种类型,一个灵活的“至少16位,如果方便的话”类型可以消除这种指令的需要。
#6
1
From the C99 rationale 7.8
Format conversion of integer types <inttypes.h>
(document that accompanies with Standard), emphasis mine:
从C99的基本原理7.8格式转换的整数类型
C89 specifies that the language should support four signed and unsigned integer data types,
char
,short
,int
andlong
, but places very little requirement on their size other than thatint
andshort
be at least 16 bits andlong
be at least as long asint
and not smaller than 32 bits. For 16-bit systems, most implementations assign 8, 16, 16 and 32 bits tochar
,short
,int
, andlong
, respectively. For 32-bit systems, the common practice is to assign 8, 16, 32 and 32 bits to these types. This difference inint
size can create some problems for users who migrate from one system to another which assigns different sizes to integer types, because Standard C’s integer promotion rule can produce silent changes unexpectedly. The need for defining an extended integer type increased with the introduction of 64-bit systems.C89指定语言应该支持四个签署和无符号整数数据类型,char,短,int和长,但地方很少要求他们大小以外,int和短至少16位和长至少只要int和不小于32位。对于16位系统,大多数实现分别将8、16、16和32位分配给char、short、int和long。对于32位系统,通常的做法是为这些类型分配8、16、32和32位。这种int大小的差异可能会给从一个系统迁移到另一个系统的用户带来一些问题,而这个系统会为整型类型分配不同的大小,因为标准C的整型提升规则会意外地产生无声的更改。定义扩展整数类型的需要随着64位系统的引入而增加。
The purpose of
<inttypes.h>
is to provide a set of integer types whose definitions are consistent across machines and independent of operating systems and other implementation idiosyncrasies. It defines, viatypedef
, integer types of various sizes. Implementations are free totypedef
them as Standard C integer types or extensions that they support. Consistent use of this header will greatly increase the portability of a user’s program across platforms.< inttypes的目的。h>提供了一组整数类型,它们的定义在不同的机器上是一致的,独立于操作系统和其他实现特性。它通过typedef定义各种大小的整数类型。实现可以*地将它们定义为它们所支持的标准C整数类型或扩展。一致地使用这个头将大大增加用户程序在跨平台上的可移植性。
The main difference between int
and int_fast16_t
is that the latter is likely to be free of these "implementation idiosyncrasies". You may think of it as something like:
int和int_fast16_t之间的主要区别是后者很可能没有这些“实现特性”。你可以这样想:
I don't care about current OS/implementation "politics" of int
size. Just give me whatever the fastest signed integer type with at least 16 bits is.
我不关心当前的操作系统/实现的int大小的“政治”。只要告诉我最快的带16位的整数类型。
#7
1
An example of how the two types might be different: suppose there’s an architecture where 8-bit, 16-bit, 32-bit and 64-bit arithmetic are equally fast. (The i386 comes close.) Then, the implementer might use a LLP64 model, or better yet allow the programmer to choose between ILP64, LP64 and LLP64, since there’s a lot of code out there that assumes long is exactly 32 bits, and that sizeof(int) <= sizeof(void*) <= sizeof(long)
. Any 64-bit implementation must violate at least one of these assumptions.
这两种类型可能不同的一个示例:假设有一个架构,其中8位、16位、32位和64位的算术都同样快。(i386接近。)然后,实现者可能会使用LLP64模型,或者更好的是让程序员在ILP64、LP64和LLP64之间进行选择,因为有很多代码假设long正好是32位,并且sizeof(int) <= sizeof(void*) <= sizeof(long)。任何64位的实现都必须至少违背其中一个假设。
In that case, int
would probably be 32 bits wide, because that will break the least code from other systems, but uint_fast16_t
could still be 16 bits wide, saving space.
在这种情况下,int可能是32位宽的,因为这会破坏其他系统中最少的代码,但是uint_fast16_t仍然可能是16位宽,节省空间。