uint32_t vs unsigned int — Which one is better?
Most C++ programmers are aware of the basic data types and their unsigned counterparts — int
vs unsigned int
, long
vs unsigned long
, etc. However, many are unaware of the various fixed-width integers defined in the <cstdint>
header, such as uint8_t
, uint16_t
, uint32_t
, and uint64_t
. So, what are they and why should anyone use them?
What are they?
Fixed-width integers, as the name implies, are integers with a fixed number of bits. A uint8_t
variable has a width of exactly 8 bits, so it can store 1 byte of data, a uint32_t
can store 32 bits bits of data, etc. There are signed versions as well, such as int32_t
that can be used if the data you are storing could be negative.
Do I need to use them?
Most people would be fine using default data types such as int
, but I would strongly suggest that systems programmers utilize fixed-width integers for the following reasons:
- Portability: A
uint32_t
is guaranteed to take up exactly 32-bits of space, whereas other types are implementation-specific. In many common systems,unsigned int
also takes up 32-bits of space, but other systems may use 64-bits. Therefore, if you require an exact number of bits for your integers no matter what processor architecture your code runs on, then fixed-width is definitely the way to go. - Efficiency: Let’s say you are writing code to simulate a traffic light. To define the possible colors of the traffic light, a sensible choice would be to use an enumeration, like this:
enum class TrafficLightColors {
Red,
Yellow,
Green
};
By default, enum class
uses int
as the default data type. Assuming that your system implements int
as a 32-bit signed integer, you could have values in the range of -2,147,483,648 to 2,147,483,647. I don’t think any traffic light in the world has that many colors…
Therefore, it would be more space efficient if you use the smallest data type possible, like uint8_t
. You can achieve that by altering your code like this:
enum class TrafficLightColors : uint8_t {
Red,
Yellow,
Green
};
This code now uses 8-bits of unsigned values to store the possible values of your traffic light colors instead of 32-bits!
Now, if you wanted to get really creative, you could forego the enumeration altogether and just use a single uint8_t
! Because you know that a traffic light only has 3 colors and a uint8_t
has 8 bits, you can encode the colors into a single byte and extract the value using bit-wise operations. This would give you 5 extra bits to encode other information about the traffic light, such as flashing-yellow, arrows vs solid colors, etc.
- Clarity: Using fixed-width integers in your code clearly conveys your intention — “I need to store a non-negative number in no more than 16-bits, so I will use the
uint16_t
data type.”