Skip to content

Commit

Permalink
Add details for n!=1 repr(packed)
Browse files Browse the repository at this point in the history
  • Loading branch information
luqmana committed Aug 15, 2024
1 parent 14649f1 commit c7ebeef
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions src/other-reprs.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,31 +119,34 @@ assert_eq!(16, size_of::<MyReprOption<&u16>>());

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 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.

[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
Expand Down

0 comments on commit c7ebeef

Please sign in to comment.