int_fast8_t 和 int_fast16_t 之间的区别
difference between int_fast8_t and int_fast16_t
我是嵌入式系统初学者,在头文件中看到int_fast8_t/int_fast16_t/int_fast32_t都是刚签名的诠释。那么它们之间有什么区别吗?还是它们基本相同,即使您将 32 位分配给 int_fast8_t,它仍然会存储 32 位而不是 8 位?
/* fastest minimum-width signed integer types */
typedef signed int int_fast8_t;
typedef signed int int_fast16_t;
typedef signed int int_fast32_t;
typedef signed __INT64 int_fast64_t;
这就是特定实现定义它们的方式。该标准要求 int_fast8_t
至少 8 位。并且它们的目的是实现应该使用它们中最快的,但是对此或如何测量它没有严格的要求。
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.
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 .
3 The following types are required:
int_fast8_t uint_fast8_t
int_fast16_t uint_fast16_t
int_fast32_t uint_fast32_t
int_fast64_t uint_fast64_t
All other types of this form are optional.
note 链接说:
- 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.
通常,“快速”变量被定义为目标处理器的本机大小,前提是它至少与指定大小一样大。请注意,这取决于更快的情况。当您有一个要对其进行操作的变量时,通常最好使用本机大小,但在大型数组上,您通常需要满足您需要的最小类型,因为数组的原始字节越大,它越差用于缓存。
例如,DOS下的Open Watcom。你有这个:
typedef signed int int_fast8_t;
typedef signed int int_fast16_t;
typedef signed long int_fast32_t;
typedef signed long long int_fast64_t;
请注意,32 位和 16 位之间存在差异,您的示例中没有。
在我的 gcc 实现中,我有这个:
typedef unsigned char uint_fast8_t;
typedef unsigned long int uint_fast16_t;
typedef unsigned long int uint_fast32_t;
typedef unsigned long int uint_fast64_t;
AFIK int8_t
在几乎所有情况下的行为都与 int_fast8_t
完全相同。但是在某些情况下您可能需要小心。看看这个程序:
#include <stdio.h>
#include <stdint.h>
int main(void) {
int_fast16_t array[] = { 12345,23456,34567 };
int16_t *ptr = array;
for(int i=0; i<3; i++) {
printf("%d %d\n", ptr[i], array[i]);
}
}
它给了我这个警告:
$ gcc main.c
main.c: In function ‘main’:
main.c:6:20: warning: initialization of ‘int16_t *’ {aka ‘short int *’} from incompatible pointer type ‘int_fast16_t *’ {aka ‘long int *’} [-Wincompatible-pointer-types]
6 | int16_t *ptr = array;
| ^~~~~
并打印:
$ ./a.out
12345 12345
0 23456
0 34567
这些类型基本上分为三类:
- 精确宽度
- 最小宽度
- 最快的最小宽度
精确宽度必须精确,但其他两个具有相同的要求但不同的目的。
在嵌入式系统中,我会为数组选择精确的宽度,为常规变量选择最快的(或者只是 int
或 long
)。如果存在精确宽度,除了便携性之外,我真的看不到最小宽度的良好用途。在这里我想指出最小和最快是标准要求,但精确宽度不是。大多数系统都支持精确宽度。因此,除非您想要 100% 的可移植性或知道您需要在不支持它的机器上编译代码,否则我总是更喜欢精确宽度而不是最小宽度。
我是嵌入式系统初学者,在头文件中看到int_fast8_t/int_fast16_t/int_fast32_t都是刚签名的诠释。那么它们之间有什么区别吗?还是它们基本相同,即使您将 32 位分配给 int_fast8_t,它仍然会存储 32 位而不是 8 位?
/* fastest minimum-width signed integer types */
typedef signed int int_fast8_t;
typedef signed int int_fast16_t;
typedef signed int int_fast32_t;
typedef signed __INT64 int_fast64_t;
这就是特定实现定义它们的方式。该标准要求 int_fast8_t
至少 8 位。并且它们的目的是实现应该使用它们中最快的,但是对此或如何测量它没有严格的要求。
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.
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 .
3 The following types are required:
int_fast8_t uint_fast8_t int_fast16_t uint_fast16_t int_fast32_t uint_fast32_t int_fast64_t uint_fast64_t
All other types of this form are optional.
note 链接说:
- 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.
通常,“快速”变量被定义为目标处理器的本机大小,前提是它至少与指定大小一样大。请注意,这取决于更快的情况。当您有一个要对其进行操作的变量时,通常最好使用本机大小,但在大型数组上,您通常需要满足您需要的最小类型,因为数组的原始字节越大,它越差用于缓存。
例如,DOS下的Open Watcom。你有这个:
typedef signed int int_fast8_t;
typedef signed int int_fast16_t;
typedef signed long int_fast32_t;
typedef signed long long int_fast64_t;
请注意,32 位和 16 位之间存在差异,您的示例中没有。
在我的 gcc 实现中,我有这个:
typedef unsigned char uint_fast8_t;
typedef unsigned long int uint_fast16_t;
typedef unsigned long int uint_fast32_t;
typedef unsigned long int uint_fast64_t;
AFIK int8_t
在几乎所有情况下的行为都与 int_fast8_t
完全相同。但是在某些情况下您可能需要小心。看看这个程序:
#include <stdio.h>
#include <stdint.h>
int main(void) {
int_fast16_t array[] = { 12345,23456,34567 };
int16_t *ptr = array;
for(int i=0; i<3; i++) {
printf("%d %d\n", ptr[i], array[i]);
}
}
它给了我这个警告:
$ gcc main.c
main.c: In function ‘main’:
main.c:6:20: warning: initialization of ‘int16_t *’ {aka ‘short int *’} from incompatible pointer type ‘int_fast16_t *’ {aka ‘long int *’} [-Wincompatible-pointer-types]
6 | int16_t *ptr = array;
| ^~~~~
并打印:
$ ./a.out
12345 12345
0 23456
0 34567
这些类型基本上分为三类:
- 精确宽度
- 最小宽度
- 最快的最小宽度
精确宽度必须精确,但其他两个具有相同的要求但不同的目的。
在嵌入式系统中,我会为数组选择精确的宽度,为常规变量选择最快的(或者只是 int
或 long
)。如果存在精确宽度,除了便携性之外,我真的看不到最小宽度的良好用途。在这里我想指出最小和最快是标准要求,但精确宽度不是。大多数系统都支持精确宽度。因此,除非您想要 100% 的可移植性或知道您需要在不支持它的机器上编译代码,否则我总是更喜欢精确宽度而不是最小宽度。