@@ -209,6 +209,35 @@ pub fn forget<T>(t: T) {
209
209
/// The mutability of a pointer does not change its size. As such, `&T` and `&mut T`
210
210
/// have the same size. Likewise for `*const T` and `*mut T`.
211
211
///
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
+ ///
212
241
/// # Examples
213
242
///
214
243
/// ```
@@ -231,6 +260,55 @@ pub fn forget<T>(t: T) {
231
260
/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>());
232
261
/// assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
233
262
/// ```
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
234
312
#[ inline]
235
313
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
236
314
#[ cfg_attr( not( stage0) , rustc_const_unstable( feature = "const_size_of" ) ) ]
0 commit comments