Is there any reason not to use fixed width integer types (e.g. uint8_t)?
byte, c, c99, integer, sizeof
Solution
It's actually quite common to store a number without needing to know the exact size of the type. There are plenty of quantities in my programs that I can reasonably assume won't exceed 2 billion, or enforce that they don't. But that doesn't mean I need an exact 32 bit type to store them, any type that can count to at least 2 billion is fine by me.
If you're trying to write very portable code, you must bear in mind that the fixed-width types are all optional.
On a C99 implementation where `CHAR_BIT` is greater than `8` there is no `int8_t`. The standard forbids it to exist because it would have to have padding bits, and `intN_t` types are defined to have no padding bits (7.18.1.1/1). `uint8_t` therefore also forbidden because (thanks, ouah) an implementation is not permitted to define `uint8_t` without `int8_t`.
So, in very portable code, if you need a signed type capable of holding values up to 127 then you should use one of `signed char`, `int`, `int_least8_t` or `int_fast8_t` according to whether you want to ask the compiler to make it:
- work in C89 (`signed char` or `int`)
- avoid surprising integer promotions in arithmetic expressions (`int`)
- small (`int_least8_t` or `signed char`)
- fast (`int_fast8_t` or `int`)
The same goes for an unsigned type up to 255, with `unsigned char`, `unsigned int`, `uint_least8_t` and `uint_fast8_t`.
If you need modulo-256 arithmetic in very portable code, then you can either take the modulus yourself, mask bits, or play games with bitfields.
In practice, most people never need to write code that portable. At the moment `CHAR_BIT > 8` only comes up on special-purpose hardware, and your general-purpose code won't get used on it. Of course that could change in future, but if it does I suspect that there is so much code that makes assumptions about Posix and/or Windows (both of which guarantee `CHAR_BIT == 8`), that dealing with your code's non-portability will be one small part of a big effort to port code to that new platform. Any such implementation is probably going to have to worry about how to connect to the internet (which deals in octets), long before it worries how to get your code up and running :-)
If you're assuming that `CHAR_BIT == 8` anyway then I don't think there's any particular reason to avoid `(u)int8_t` other than if you want the code to work in C89. Even in C89 it's not that difficult to find or write a version of `stdint.h` for a particular implementation. But if you can easily write your code to only require that the type can hold `255`, rather than requiring that it can't hold `256`, then you might as well avoid the dependency on `CHAR_BIT == 8`.
Problem
Assuming you're using a compiler that supports C99 (or even just stdint.h), is there any reason not to use fixed-width integer types such as uint8_t? One reason that I'm aware of is that it makes much more sense to use `char`s when dealing with characters instead of using `(u)int8_t`s, as mentioned in this question. But if you are planning on storing a number, when would you want to use a type that you don't know how big it is? I.e. In what situation would you want to store a number in an `unsigned short` without knowing if it is 8, 16, or even 32 bits, instead of using a `uint16t`? Following on from this, is it considered better practice to use fixed-width integers, or to use the normal integer types and just never assume anything and use `sizeof` wherever you need to know how many bytes they are using?