Integer Limits and Types In C/C++
Unlike Java or C#, primitive data types in C++ can vary in size depending on the platform. For example, int is not guaranteed to be a 32-bit integer. The size of basic C++ types depends on
-
The Architecture (16 bits, 32 bits, 64 bits)
You can expect std::size_t to always represent the unsigned native integer size on current architecture. i.e. 16-bit, 32-bit or 64-bit. e.g
On a x64-bit machine, with x86_64 hardware-platform and processor,
sizeof(std::size_t) == sizeof(unsigned int) == 8
where as, on a 32-bit machine, with i386 hardware-platform and i686 processor,
sizeof(std::size_t) == sizeof(unsigned int) == 4
But as far as all the other built-in types go, it really depends on the compiler.
-
The Compiler
The C++ standard does not specify the size of integral types in bytes, but it specifies minimum ranges they must be able to hold. You can infer minimum size in bits from the required range and the value of CHAR_BIT
macro in <climits>, that defines the number of bits in a byte (in all but the most obscure platforms it’s 8).
An important point to note for char
is that its size is always 1 byte, or CHAR_BIT
bits (hence the name). char is always a byte , but it’s not always an octet. A byte is the smallest addressable unit of memory (in most definitions), an octet is 8-bit unit of memory.
i.e sizeof(char) == 1
for all implementations, but CHAR_BIT
defines the size of a byte for a platform and it’s not always 8 bit. There are platforms with 16-bit and 32-bit bytes, hence char will take up more than 8 bits, but it is still a byte.
A C++ (or C) implementation can define the size of a type in bytes sizeof(type)
to any value, as long as
- the expression
sizeof(type) * CHAR_BIT
evaluates to the number of bits enough to contain required ranges, and - the ordering of type is still valid (e.g.
sizeof(int) <= sizeof(long)
).
The actual implementation-specific ranges can be found in <limits.h> header in C, or <climits> in C++ (or even better, templated std::numeric_limits in <limits> header). Minimum ranges required by the standard (page 22) can be found using this C++ snippet:
Portability
If you are concerned with portability and want guaranteed size, or you want the name of the type reflects the size,
- You can use the header BOOST cstdint. It’s usually better than inventing your own wheel(which incurs the maintainence and testing), or
- You can use the header <cinttypes>, where the following macros are available:
int8_t, int16_t, int32_t, uint8_t, uint16_t, uint32_t
etc.
For more information on this, refer Wiki- Inttypes.h.