131

The documentation says usize is

Operations and constants for pointer-sized unsigned integers.

In most cases, I can replace usize with u32 and nothing happens. So I don't understand why we need two types which are so alike.

Vayn
  • 2,507
  • 4
  • 27
  • 33

2 Answers2

197

Warning: This answer is legacy for Rust, usize have been redefined as "can hold any memory location", see 95228 for very deep reasoning, TL;DR: a pointer is not just a number.


As the documentation states usize is pointer-sized, thus its actual size depends on the architecture you are compiling your program for.

As an example, on a 32 bit x86 computer, usize = u32, while on x86_64 computers, usize = u64.

usize gives you the guarantee to be always big enough to hold any pointer or any offset in a data structure, while u32 can be too small on some architectures.

Stargateur
  • 24,473
  • 8
  • 65
  • 91
Levans
  • 14,196
  • 3
  • 49
  • 53
  • 7
    Should I always use `usize` type for safety? – Vayn Apr 12 '15 at 17:49
  • 29
    Depends on what you want to do, if holding indexes in a memory structure, yes. For plain numbers, `u32` is often good. The standard library always use `usize` when appropriate, and rust won't silently convert a `u32` to a `usize`, so you'll see when they are needed. – Levans Apr 12 '15 at 17:53
  • 7
    `u32` can also be too big if you're working on embedded systems, which Rust as a systems language is designed to work well with. If `u32` was _always_ too small, the language probably would've been designed to silently convert `u32` into `usize`. – Nicholas Pipitone Oct 31 '18 at 23:02
  • 7
    Note that `usize` might cause confusion in cases you are interested in deterministic behavior or serialisation. – Kostas Kryptos May 15 '19 at 00:45
  • @NicholasPipitone Probably not like `u8` cannot be silently converted to `u16`. But it would've been provided `into()` and not just `try_into()`. – Chayim Friedman Aug 30 '22 at 22:18
  • @ChayimFriedman Yes, that's more accurate. Had `u32` been guaranteed to be <= `usize` (No embedded systems), then `usize` would've been provided `into()` but not silent conversion. And we get neither bc `usize` can be 8bit, 16bit, 32bit, 64bit, anything~ – Nicholas Pipitone Nov 04 '22 at 13:50
15

Adding to @Levans' answer,

The size of usize is depended on how much size it takes to reference any location in memory.

on a 32 bit target usize is 4 bytes and on a 64 bit target usize is 8 bytes

All Іѕ Vаиітy
  • 24,861
  • 16
  • 87
  • 111
  • 1
    How is this answer different from @Levans' answer? – ynn Aug 17 '22 at 13:40
  • 1
    I think this answer is a complement to @Leavans's answer. According to the rust documentation, usize is a pointer-sized integer, which means another difference of usize to u32 is, according to this answer. – Yuchen Aug 24 '22 at 08:47