Skip to content

Commit e686b02

Browse files
authored
Merge pull request #216 from carbotaniuman/patch-1
Add size != stride to frequently requested changes
2 parents 3c1745a + aec954e commit e686b02

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

src/frequently-requested-changes.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,42 @@ statement, and only later see the `if` and realize it's a conditional return.
178178

179179
Such a change would also have non-obvious evaluation order (evaluating the
180180
condition before the return expression).
181+
182+
## Size != Stride
183+
184+
Rust assumes that the size of an object is equivalent to the stride of an object -
185+
this means that the size of `[T; N]` is `N * std::mem::size_of::<T>`. Allowing
186+
size to not equal stride may allow objects that take up less space in arrays due
187+
to the reuse of tail padding, and allow interop with other languages with this behavior.
188+
189+
One downside of this assumption is that types with alignment greater than their size can
190+
waste large amounts of space due to padding. An overaligned struct such as the following:
191+
```
192+
#[repr(C, align(512))]
193+
struct Overaligned(u8);
194+
```
195+
will store only 1 byte of data, but will have 511 bytes of tail padding for a total size of
196+
512 bytes. This tail padding will not be reusable, and adding `Overaligned` as a struct field
197+
may exacerbate this waste as additional trailing padding be included after any other members.
198+
199+
Rust makes several guarantees that make supporting size != stride difficult in the general case.
200+
The combination of `std::array::from_ref` and array indexing is a stable guarantee that a pointer
201+
(or reference) to a type is convertible to a pointer to a 1-array of that type, and vice versa.
202+
203+
Such a change could also pose problems for existing unsafe code, which may assume that pointers
204+
can be manually offset by the size of the type to access the next array element. Unsafe
205+
code may also assume that overwriting trailing padding is allowed, which would conflict with
206+
the repurposing of such padding for data storage.
207+
208+
While changing the fundamental layout guarantees seems unlikely, it may be reasonable to add additional
209+
inspection APIs for code that wishes to opt into the possibility of copying smaller parts of an object
210+
-- an API to find out that copying only bytes `0..1` of `Overaligned` is sufficient might still be
211+
reasonable, or something `size_of_val`-like that could be variant-aware to say which bytes are sufficient
212+
for copying a particular instance. Similarly, move-only fields may allow users to mitigate the effects
213+
of tail or internal padding, as they can be reused due to the lack of a possible reference or pointer.
214+
215+
Cross-referencing to other discussions:
216+
217+
* https://github.com/rust-lang/rfcs/issues/1397
218+
* https://github.com/rust-lang/rust/issues/17027
219+
* https://github.com/rust-lang/unsafe-code-guidelines/issues/176

0 commit comments

Comments
 (0)