Docs for size_of::<#[repr(C)]> items.
Most of this info comes from camlorn's blog post on optimizing struct layout and the Rustonomicon.
This commit is contained in:
parent
1c4510adc8
commit
0118398291
@ -209,6 +209,35 @@ pub fn forget<T>(t: T) {
|
||||
/// 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`.
|
||||
///
|
||||
/// # Size of #[repr(C)] items
|
||||
///
|
||||
/// The `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.
|
||||
///
|
||||
/// ## Structs
|
||||
///
|
||||
/// For `structs`, the size is determined by the following algorithm.
|
||||
///
|
||||
/// For each field in the struct ordered by declaration order:
|
||||
///
|
||||
/// 1. Add the size of the field.
|
||||
/// 2. Round up the current size to the nearest multiple of the next field's [alignment].
|
||||
///
|
||||
/// Finally, round the size of the struct to the nearest multiple of its [alignment].
|
||||
///
|
||||
/// Unlike `C`, zero sized structs are not rounded up to one byte in size.
|
||||
///
|
||||
/// ## Enums
|
||||
///
|
||||
/// Enums that carry no data other than the descriminant have the same size as C enums
|
||||
/// on the platform they are compiled for.
|
||||
///
|
||||
/// ## Unions
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
@ -231,6 +260,55 @@ pub fn forget<T>(t: T) {
|
||||
/// 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, 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>());
|
||||
/// ```
|
||||
///
|
||||
/// [alignment]: ./fn.align_of.html
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_size_of"))]
|
||||
|
Loading…
x
Reference in New Issue
Block a user