简体   繁体   中英

Overflow behaviour of fast types from stdint.h

C99 and C++11 (and before them POSIX) introduced least and fast types in the stdint header, eg int_fast16_t or uint_fast8_t .

I wonder what guarantees of the overflow behaviour of these types are given. 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, and thus be faster.

The overflow rules are the same as for any signed/unsigned integer variable.

uint_fast16_t is mapped to the fastest size that is at least 16 bits. If the fastest size happens to be 32 bits on a platform then the behaviour would be different. Consider:

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)

The guarantees are exactly the same. Signed integers will overflow, and unsigned will wrap around. The maximum value that can be represented depends on which integer type the the type is an alias of.

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

It can be an alias of any unsigned integer type that is at least 8 bits wide.

C11 n1570 says that the

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 .


Thus no behaviour is guaranteed as such; what these say is that int_fastN_t must not have signed overflow in the range 2^(n-1) - 1 ... 2^(n-1) - 1 ; uint_fastN_t must not have a wraparound for values less than 2^n - 1 . If you need a more exact wraparound behaviour, then do not use the fast types, and instead use the exact width types (aka intN_t and uintN_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.

Firstly, there doesn't have to be a uint8_t type. On a 36-bit word addressed machine (they have existed), a char would probably be 9 bits wide. ( Word addressed means that the natural way to access memory is in words (of some size). Addressing sub-sections of a word requires shifting and masking, and pointers which address such sub-sections need additional bits to refer to the sub-unit within the word.)

On such a machine, the compiler author would have the interesting decision as whether to make uint_fast8_t be the same as unsigned char (9 bits) or the 36-bit unsigned int type.

As others have said, there will be an implementation defined maximum of these types, and if you exceed that limit the unsigned types will wrap and the signed types will cause undefined behaviour.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM