I'm learning rust and curious to know the purpose that we can allocate memory sizes to data types. I'm not clear yet how this could be an advantage. It can definitely save up some memory space but I ran into a similar thread that stated memory is the least of the concern.
The answer is as always "it depends". If it was a feature with no value, nobody would have put it in the language. If it was a feature which always had value, it would be the default.
Situations in which you should do it:
- You have an actual functional reason for caring about how many bits there are in your data types; most likely these days this means you know that it will overflow the size of an
i32(or similar for non-integer types).
- You have actually profiled your code in production and found that the hot path can be improved by using a specific size.
Situations in which you shouldn't do it:
The primary value in Rust of allocating a size is allocating a defined range that is uniform. There are very few ways to actually observe the in-memory size of a value in rust. However overflow, eg adding 1 to a u8 containing the value 255 is very obvious and different from anything lower. And for a rust value you always know the range is 0 to
So why do we need a range? We could make integers able to hold infinite values like Haskell and Python, but that requires dynamic memory allocation to hold arbitrarily large values. And Rust is designed not to require an allocator for core functionality.
C and C++ don't specify an exact range in the standard, instead specifying a number of properties (minimum size, and comparative size between types) that the range must fulfill. They then make it implementation defined as to what the exact range is. This means that switching to a new platform has often resulted in issues in the codebase from overflow happening at unexpected values. If the codebase is sufficiently validated, this will just leave a codebase with significant manual effort to fix, and often significant additional complexity. If the codebase is not sufficiently validated, these issues can result in hidden bugs that may not surface until late in production.
So compilers have sort of standardized on a convention in those languages as to what the ranges are in most scenarios.
Alternatively we could be like Java and C# where there are
short but they always have a defined range in the standard. In practice this is effectively the same as what Rust does, but with the overhead you have to memorize the range rather than 0..(2^n) for all unsigned types.
So yes, you could in a lot of cases just use i32s for everything. But you still have to use a type that expresses the implicit assumption that you are limited to values up to (2^31)-1.