From 6120f45d994328b8dd2c89d65f7b6f518d849157 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 15 Aug 2024 15:15:13 -0700 Subject: [PATCH] Add details for n!=1 repr(packed) --- src/other-reprs.md | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/other-reprs.md b/src/other-reprs.md index 289da57..b7d04fc 100644 --- a/src/other-reprs.md +++ b/src/other-reprs.md @@ -119,31 +119,34 @@ assert_eq!(16, size_of::>()); This optimization still applies to fieldless enums with an explicit `repr(u*)`, `repr(i*)`, or `repr(C)`. -## repr(packed) +## repr(packed), repr(packed(n)) -`repr(packed)` forces Rust to strip any padding, and only align the type to a -byte. This may improve the memory footprint, but will likely have other negative -side-effects. +`repr(packed(n))` (where `n` is a power of two) forces the type to have an +alignment of *at most* `n`. Most commonly used without an explicit `n`, +`repr(packed)` is equivalent to `repr(packed(1))` which forces Rust to strip +any padding, and only align the type to a byte. This may improve the memory +footprint, but will likely have other negative side-effects. -In particular, most architectures *strongly* prefer values to be aligned. This -may mean the unaligned loads are penalized (x86), or even fault (some ARM -chips). For simple cases like directly loading or storing a packed field, the -compiler might be able to paper over alignment issues with shifts and masks. -However if you take a reference to a packed field, it's unlikely that the -compiler will be able to emit code to avoid an unaligned load. +In particular, most architectures *strongly* prefer values to be naturally +aligned. This may mean that unaligned loads are penalized (x86), or even fault +(some ARM chips). For simple cases like directly loading or storing a packed +field, the compiler might be able to paper over alignment issues with shifts +and masks. However if you take a reference to a packed field, it's unlikely +that the compiler will be able to emit code to avoid an unaligned load. [As this can cause undefined behavior][ub loads], the lint has been implemented and it will become a hard error. -`repr(packed)` is not to be used lightly. Unless you have extreme requirements, -this should not be used. +`repr(packed)/repr(packed(n))` is not to be used lightly. Unless you have +extreme requirements, this should not be used. -This repr is a modifier on `repr(C)` and `repr(Rust)`. +This repr is a modifier on `repr(C)` and `repr(Rust)`. For FFI compatibilty +you most likely always want to be explicit: `repr(C, packed)`. ## repr(align(n)) `repr(align(n))` (where `n` is a power of two) forces the type to have an -alignment of *at least* n. +alignment of *at least* `n`. This enables several tricks, like making sure neighboring elements of an array never share the same cache line with each other (which may speed up certain