First off, Microsoft's implementation does support <stdint.h>
.
Use the appropriate type for what you're doing.
If you need, for example, an unsigned type that's exactly 16 bits wide with no padding bits, use uint16_t
, defined in <stdint.h>
.
If you need an unsigned type that's at least 16 bits wide, you can use uint_least16_t
, or uint_fast16_t
, or short
, or int
.
You probably don't need exact-width types as often as you think you do. Very often what matters is not the exact size of a type, but the range of values it supports. But exact representation is important when you're interfacing to some externally defined data format. In that case, you should already have declarations that tell you what types to use.
There are specific requirements on the ranges of the predefined types: char
is at least 8 bits, short
and int
are at least 16 bits, long
is at least 32 bits, and long long
is at least 64 bits. Also, short
is at least as wide as char
, int
is at least as wide as short
, and so forth. (The standard specifies minimum ranges, but the minimum sizes can be derived from the ranges and the fact that a binary representation is required.)
Note that <stdint.h>
is a C header. If you #include
it in a C++ program, the type names will be imported directly into the global namespace, and may or may not also be imported into the std
namespace. If you #include <cstdint>
, then the type names will be imported into the std
namespace, and may or may not also be imported into the global namespace. Macro names such as UINT32_MAX
are not in any namespace; they're always global. You can use either version of the header; just be consistent about using or not using the std::
prefix.