pub const fn size_of<T>() -> usize
Returns the size of a type in bytes.
More specifically, this is the offset in bytes between successive elements in an array with that item type including alignment padding. Thus, for any type T
and length n
, [T; n]
has a size of n * size_of::<T>()
.
In general, the size of a type is not stable across compilations, but specific types such as primitives are.
The following table gives the size for primitives.
Type | size_of::<Type>() |
---|---|
() | 0 |
bool | 1 |
u8 | 1 |
u16 | 2 |
u32 | 4 |
u64 | 8 |
u128 | 16 |
i8 | 1 |
i16 | 2 |
i32 | 4 |
i64 | 8 |
i128 | 16 |
f32 | 4 |
f64 | 8 |
char | 4 |
Furthermore, usize
and isize
have the same size.
The types *const T
, &T
, Box<T>
, Option<&T>
, and Option<Box<T>>
all have the same size. If T
is Sized, all of those types have the same size as usize
.
The mutability of a pointer does not change its size. As such, &T
and &mut T
have the same size. Likewise for *const T
and *mut T
.
#[repr(C)]
itemsThe C
representation for items has a defined layout. With this layout, the size of items is also stable as long as all fields have a stable size.
For structs
, the size is determined by the following algorithm.
For each field in the struct ordered by declaration order:
Finally, round the size of the struct to the nearest multiple of its alignment. The alignment of the struct is usually the largest alignment of all its fields; this can be changed with the use of repr(align(N))
.
Unlike C
, zero sized structs are not rounded up to one byte in size.
Enums that carry no data other than the discriminant have the same size as C enums on the platform they are compiled for.
The size of a union is the size of its largest field.
Unlike C
, zero sized unions are not rounded up to one byte in size.
use std::mem; // Some primitives assert_eq!(4, mem::size_of::<i32>()); assert_eq!(8, mem::size_of::<f64>()); assert_eq!(0, mem::size_of::<()>()); // Some arrays assert_eq!(8, mem::size_of::<[i32; 2]>()); assert_eq!(12, mem::size_of::<[i32; 3]>()); assert_eq!(0, mem::size_of::<[i32; 0]>()); // Pointer size equality assert_eq!(mem::size_of::<&i32>(), mem::size_of::<*const i32>()); assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Box<i32>>()); assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>()); assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
Using #[repr(C)]
.
use std::mem; #[repr(C)] struct FieldStruct { first: u8, second: u16, third: u8 } // The size of the first field is 1, so add 1 to the size. Size is 1. // The alignment of the second field is 2, so add 1 to the size for padding. Size is 2. // The size of the second field is 2, so add 2 to the size. Size is 4. // The alignment of the third field is 1, so add 0 to the size for padding. Size is 4. // The size of the third field is 1, so add 1 to the size. Size is 5. // Finally, the alignment of the struct is 2 (because the largest alignment amongst its // fields is 2), so add 1 to the size for padding. Size is 6. assert_eq!(6, mem::size_of::<FieldStruct>()); #[repr(C)] struct TupleStruct(u8, u16, u8); // Tuple structs follow the same rules. assert_eq!(6, mem::size_of::<TupleStruct>()); // Note that reordering the fields can lower the size. We can remove both padding bytes // by putting `third` before `second`. #[repr(C)] struct FieldStructOptimized { first: u8, third: u8, second: u16 } assert_eq!(4, mem::size_of::<FieldStructOptimized>()); // Union size is the size of the largest field. #[repr(C)] union ExampleUnion { smaller: u8, larger: u16 } assert_eq!(2, mem::size_of::<ExampleUnion>());
© 2010 The Rust Project Developers
Licensed under the Apache License, Version 2.0 or the MIT license, at your option.
https://doc.rust-lang.org/std/mem/fn.size_of.html