OpenBSD integer types
I’ll start with the very basic int types, then list some of the more common aliases provided and which basic type they map to. Again, this info is only relevant for OpenBSD. Some remarks about other systems are at the end.
OpenBSD architectures come in two sizes, ILP32 and I32LP64, though the latter is commonly referred to as just LP64. The letters stand for Integer, Long, Pointer, and the number is of course the number of bits. More on this later. Without further ado, the basic types:
char - always 8 bits, but not always signed or unsigned. If you care about signedness, you must specify it.
short - always 16 bits.
int - always 32 bits.
long - machine word width, either 32 or 64 bits. Same size as a pointer.
long long - always 64 bits.
int8_t, int32_t, int64_t, ... - obvious types are obvious.
size_t, ssize_t, ptrdiff_t, intptr_t, ... - generally the long type, as these types relate to the amount of addressable memory and that’s the type that changes size. (May be signed or unsigned, depending on which type it is.) You shouldn’t really need to know the exact type.
intmax_t, off_t - always 64 bits.
As you can see, long is the only basic type that changes size, hence the LP64 or not LP64 distinction. It’s also frequently the type behind other types, like size_t. Do not depend on that. Some architectures, for whatever reason, may use int (if 32 bit) or long long (if 64 bit) as their size_t implementation. If you need to know, you are asking the wrong question.
These types are fairly typical on many platforms, though a notable exception is 64 bit Windows. Microsoft chose to keep long as 32 bits. Their choice is somewhat regrettable because it means lots of software that probably could have been 64 bit ready is not, but it also makes sense given the history. Old school DOS programs used int for 16 bits and long for 32 bits. So lots of programmers got used to spelling “32 bit int” as long. Now they’re stuck, highlighting one of the perils of using the wrong spelling for the same type. If writing size_t had been more in vogue, there’d be less trouble today. Using the identification scheme above, 64 bit Windows is an IL32P64 architecture. There are also other combinations, like ILP64 machines. (OpenBSD doesn’t run on any.)
My recommendation (not that I always follow it; it’s easier to teach than to do) is to always use the correct semantic type, like size_t or ptrdiff_t. Fixed size types are also ok, because they’re fixed (duh!). int is ok if you really don’t care what the size is, you just need a place to stick a flag or an error code. But I don’t see much use for short or long in correct portable code. If you want to save space because an int may be too big, you should pick the size you know you need (int16_t, int8_t), not just the “something a little smaller” short.
Apropos quote from deraadt: “OK, situation dire. I don’t know if all the time_t bugs can be fixed before 2038.”