Note that here again, actually reading the standard helps.
Summing it up "quickly":
- stdint.h defines integer types that are guaranteed to be of an exact width, and others that are guaranteed to be at least some specified width. Those are respectively intN_t/uint_Nt and uint_leastN_t/int_leastN_t (the latter are well less known).
- None of the former are actually REQUIRED to be implemented. Your particular implementation may contain NONE, or just some of them. It's pretty rare that there be none, but the 64-bit ones may, for instance, not be implemented. The standard says: "these types are optional".
- For the latter, as far as I've gotten it, 8, 16, 32 and 64 are REQUIRED. Others are optional. So a conforming C99 compiler shoud actually define int_least64_t for instance, but may not define int64_t. The standard says: "The following types are required:" and lists int_leastN_t/uint_leastN_t for N=8, 16, 32, 64. (I would then conclude that any compiler NOT defining int_least64_t, for instance, IS non-conforming. But it may absolutely not define int64_t.)
- Some implementations may define other, more exotic widths such as 24 bits. This is allowed, but strictly optional of course, and in practice, a lot less common than the more ubiquitous 8, 16, 32, 64 (which again may not all be defined either...)
- There are yet other categories of integer types, such as intptr_t/uintptr_t, which are useful everytime you need to cast a pointer to an integer. This is the only conforming way of doing it. But those types are also optional per the standard. They are commonly defined on implementations targetting platforms with non-segmented addresses, and may not be defined on the latter. This is of course just a technical constraint, nothing is written about that in the standard.
- AFAIK, nothing specific is said about arithmetic with stdint types, so those merely define 'storage', which is kinda obvious in a way, since in C, all a typedef can do is define a derived type, not how operations should be performed on them. Thus, we can infer from the standard that stdint types just inherit the rules from the base integer C types. Which is, admittedly, not very consistent (but that is, OTOH, understandable, as the comittee decided to provide stdint's only through a standard header, and not through any extension of the language itself. This point is important. To ensure proper arithmetics with those types, it's definitely not trivial. You need cautious casting of intermediate computations all over the place, and you need not to assume anything much. To understand this particular point, you need to have a (very) good understanding of the C language.
Of course, the moral of the story is NOT that you shouldn't use some particular standardized feature (like for instance stdint here) just because many points of it are optional per the standard. Of course, you always have to know your tools. If something is not available on your particular implementation, you will obviously not be able to use it. But you should definitely use all that's available, and find decently elegant ways of implementing the rest (as I said, in seperate headers/source files).
And yes you also have to dig a little deeper... and stdint.h is actually a good example of why reading the standard will definitely help. You're not likely to find in-depth knowledge of how to use stdint.h types properly in any cheat sheet, and not that likely to find that in many books on C.
Finally, this is also an example of C being an high-level language (despite what some may say). stdint's are provided for data structures, storage and data exchange, not for fixed-width arithmetics. C is not assembly. C is not object-oriented either (at least per se), so you can't redefine operators for new types, which would have allowed guaranteed, fixed-width arithmetic for each integer type defined in stdint.h...
As I said before, many other high-level languages would exhibit the same "problem" with arithmetics. And yes, you can work around that with those that can redefine basic operators.
In C, it takes a lot more careful approach.