@@ -209,6 +209,35 @@ pub fn forget<T>(t: T) {
209209/// The mutability of a pointer does not change its size. As such, `&T` and `&mut T`
210210/// have the same size. Likewise for `*const T` and `*mut T`.
211211///
212+ /// # Size of `#[repr(C)]` items
213+ ///
214+ /// The `C` representation for items has a defined layout. With this layout,
215+ /// the size of items is also stable as long as all fields have a stable size.
216+ ///
217+ /// ## Size of Structs
218+ ///
219+ /// For `structs`, the size is determined by the following algorithm.
220+ ///
221+ /// For each field in the struct ordered by declaration order:
222+ ///
223+ /// 1. Add the size of the field.
224+ /// 2. Round up the current size to the nearest multiple of the next field's [alignment].
225+ ///
226+ /// Finally, round the size of the struct to the nearest multiple of its [alignment].
227+ ///
228+ /// Unlike `C`, zero sized structs are not rounded up to one byte in size.
229+ ///
230+ /// ## Size of Enums
231+ ///
232+ /// Enums that carry no data other than the descriminant have the same size as C enums
233+ /// on the platform they are compiled for.
234+ ///
235+ /// ## Size of Unions
236+ ///
237+ /// The size of a union is the size of its largest field.
238+ ///
239+ /// Unlike `C`, zero sized unions are not rounded up to one byte in size.
240+ ///
212241/// # Examples
213242///
214243/// ```
@@ -231,6 +260,55 @@ pub fn forget<T>(t: T) {
231260/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>());
232261/// assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
233262/// ```
263+ ///
264+ /// Using `#[repr(C)]`.
265+ ///
266+ /// ```
267+ /// use std::mem;
268+ ///
269+ /// #[repr(C)]
270+ /// struct FieldStruct {
271+ /// first: u8,
272+ /// second: u16,
273+ /// third: u8
274+ /// }
275+ ///
276+ /// // The size of the first field is 1, so add 1 to the size. Size is 1.
277+ /// // The alignment of the second field is 2, so add 1 to the size for padding. Size is 2.
278+ /// // The size of the second field is 2, so add 2 to the size. Size is 4.
279+ /// // The alignment of the third field is 1, so add 0 to the size for padding. Size is 4.
280+ /// // The size of the third field is 1, so add 1 to the size. Size is 5.
281+ /// // Finally, the alignment of the struct is 2, so add 1 to the size for padding. Size is 6.
282+ /// assert_eq!(6, mem::size_of::<FieldStruct>());
283+ ///
284+ /// #[repr(C)]
285+ /// struct TupleStruct(u8, u16, u8);
286+ ///
287+ /// // Tuple structs follow the same rules.
288+ /// assert_eq!(6, mem::size_of::<TupleStruct>());
289+ ///
290+ /// // Note that reordering the fields can lower the size. We can remove both padding bytes
291+ /// // by putting `third` before `second`.
292+ /// #[repr(C)]
293+ /// struct FieldStructOptimized {
294+ /// first: u8,
295+ /// third: u8,
296+ /// second: u16
297+ /// }
298+ ///
299+ /// assert_eq!(4, mem::size_of::<FieldStructOptimized>());
300+ ///
301+ /// // Union size is the size of the largest field.
302+ /// #[repr(C)]
303+ /// union ExampleUnion {
304+ /// smaller: u8,
305+ /// larger: u16
306+ /// }
307+ ///
308+ /// assert_eq!(2, mem::size_of::<ExampleUnion>());
309+ /// ```
310+ ///
311+ /// [alignment]: ./fn.align_of.html
234312#[ inline]
235313#[ stable( feature = "rust1" , since = "1.0.0" ) ]
236314#[ cfg_attr( not( stage0) , rustc_const_unstable( feature = "const_size_of" ) ) ]
0 commit comments