From 548686ff12322f948652ee6523074b2ce6d2bb06 Mon Sep 17 00:00:00 2001 From: Havvy Date: Sat, 16 Sep 2017 20:40:05 -0700 Subject: [PATCH] Document stable size_of primitives and pointer size guarantees --- src/libcore/mem.rs | 48 ++++++++++++++++++++++++++++++++++-- src/libstd/primitive_docs.rs | 8 ++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 3e24623dad895..e98dab739cb02 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -177,15 +177,59 @@ pub fn forget(t: T) { /// Returns the size of a type in bytes. /// -/// More specifically, this is the offset in bytes between successive -/// items of the same type, including alignment padding. +/// 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::()`. +/// +/// 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::\() +/// ---- | --------------- +/// () | 0 +/// u8 | 1 +/// u16 | 2 +/// u32 | 4 +/// u64 | 8 +/// i8 | 1 +/// i16 | 2 +/// i32 | 4 +/// i64 | 8 +/// f32 | 4 +/// f64 | 8 +/// char | 4 +/// +/// Furthermore, `usize` and `isize` have the same size. +/// +/// The types `*const T`, `&T`, `Box`, `Option<&T>`, and `Option>` 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`. /// /// # Examples /// /// ``` /// use std::mem; /// +/// // Some primitives /// assert_eq!(4, mem::size_of::()); +/// assert_eq!(8, mem::size_of::()); +/// 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::>()); +/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::>()); +/// assert_eq!(mem::size_of::>(), mem::size_of::>>()); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 76ef36cc9a733..1edb35d8fe741 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -710,6 +710,10 @@ mod prim_u128 { } // /// The pointer-sized signed integer type. /// +/// The size of this primitive is how many bytes it takes to reference any +/// location in memory. For example, on a 32 bit target, this is 4 bytes +/// and on a 64 bit target, this is 8 bytes. +/// /// *[See also the `std::isize` module](isize/index.html).* /// /// However, please note that examples are shared between primitive integer @@ -722,6 +726,10 @@ mod prim_isize { } // /// The pointer-sized unsigned integer type. /// +/// The size of this primitive is how many bytes it takes to reference any +/// location in memory. For example, on a 32 bit target, this is 4 bytes +/// and on a 64 bit target, this is 8 bytes. +/// /// *[See also the `std::usize` module](usize/index.html).* /// /// However, please note that examples are shared between primitive integer