来自 stdint.h 的快速类型的溢出行为

Overflow behaviour of fast types from stdint.h

C99 和 C++11(以及之前的 POSIX)在 stdint header 中引入了 leastfast 类型,例如int_fast16_tuint_fast8_t.

我想知道这些类型的溢出行为有什么保证。如果这些与 "normal" 整数类型相同(以便无符号类型在溢出时回绕),我想知道 uint_fast8_t 实际上如何映射到与 fixed-witdh uint8_t 类型,因此速度更快。

溢出规则与任何 signed/unsigned 整数变量相同。

uint_fast16_t 映射到至少 16 位的最快大小。如果平台上最快的大小恰好是 32 位,则行为会有所不同。考虑:

uint_fast16_t k = 1 << 16;

if (k == 0) {
    printf("k is 16 bits\n");
} else {
    printf("k is larger than 16 bits\n");
}

If these are the same as for "normal" integer types (so that unsigned types wrap around on overflow)

保障完全一样。有符号整数会溢出,无符号整数会回绕。可以表示的最大值取决于该类型是哪个整数类型的别名。

I wonder how uint_fast8_t can actually be mapped to any different type than the fixed-witdh uint8_t type

它可以是至少 8 位宽的任何无符号整数类型的别名。

C11 n1570 表示

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 .


因此不能保证任何行为;这些说的是 int_fastN_t 不能在 2^(n-1) - 1 ... 2^(n-1) - 1 范围内有符号溢出; uint_fastN_t 不得对小于 2^n - 1 的值进行环绕。如果你需要更精确的环绕行为,那么不要使用快速类型,而是使用精确宽度类型(又名 intN_tuintN_t)。

I wonder how uint_fast8_t can actually be mapped to any different type than the fixed-width uint8_t type, and thus be faster.

首先,不必 uint8_t 类型。在 36 位字寻址机器上(它们已经存在),char 可能是 9 位宽。 (Word addressed 意味着访问内存的自然方式是 words(某种大小)。寻址一个字的子部分需要移位和掩码和寻址此类子部分的指针需要额外的位来指代字内的子单元。)

在这样的机器上,编译器作者会有一个有趣的决定,即是使 uint_fast8_tunsigned char(9 位)相同还是 36 位 unsigned int类型。

正如其他人所说,将有一个实现定义这些类型的最大值,如果超过该限制,无符号类型将换行,而有符号类型将导致未定义的行为。