Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

other-reprs: Add details for n!=1 repr(packed) #460

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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
Expand Down