Skip to content

Commit

Permalink
deploy: e686b02
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Oct 18, 2023
1 parent b082ab1 commit df2eb1e
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
1 change: 0 additions & 1 deletion CNAME

This file was deleted.

32 changes: 32 additions & 0 deletions frequently-requested-changes.html
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,38 @@ <h2 id="suffix-modifiers-if-after-returnbreakcontinue-or-after-arbitrary-stateme
statement, and only later see the <code>if</code> and realize it's a conditional return.</p>
<p>Such a change would also have non-obvious evaluation order (evaluating the
condition before the return expression).</p>
<h2 id="size--stride"><a class="header" href="#size--stride">Size != Stride</a></h2>
<p>Rust assumes that the size of an object is equivalent to the stride of an object -
this means that the size of <code>[T; N]</code> is <code>N * std::mem::size_of::&lt;T&gt;</code>. Allowing
size to not equal stride may allow objects that take up less space in arrays due
to the reuse of tail padding, and allow interop with other languages with this behavior.</p>
<p>One downside of this assumption is that types with alignment greater than their size can
waste large amounts of space due to padding. An overaligned struct such as the following:</p>
<pre><code>#[repr(C, align(512))]
struct Overaligned(u8);
</code></pre>
<p>will store only 1 byte of data, but will have 511 bytes of tail padding for a total size of
512 bytes. This tail padding will not be reusable, and adding <code>Overaligned</code> as a struct field
may exacerbate this waste as additional trailing padding be included after any other members.</p>
<p>Rust makes several guarantees that make supporting size != stride difficult in the general case.
The combination of <code>std::array::from_ref</code> and array indexing is a stable guarantee that a pointer
(or reference) to a type is convertible to a pointer to a 1-array of that type, and vice versa.</p>
<p>Such a change could also pose problems for existing unsafe code, which may assume that pointers
can be manually offset by the size of the type to access the next array element. Unsafe
code may also assume that overwriting trailing padding is allowed, which would conflict with
the repurposing of such padding for data storage.</p>
<p>While changing the fundamental layout guarantees seems unlikely, it may be reasonable to add additional
inspection APIs for code that wishes to opt into the possibility of copying smaller parts of an object
-- an API to find out that copying only bytes <code>0..1</code> of <code>Overaligned</code> is sufficient might still be
reasonable, or something <code>size_of_val</code>-like that could be variant-aware to say which bytes are sufficient
for copying a particular instance. Similarly, move-only fields may allow users to mitigate the effects
of tail or internal padding, as they can be reused due to the lack of a possible reference or pointer.</p>
<p>Cross-referencing to other discussions:</p>
<ul>
<li>https://github.com/rust-lang/rfcs/issues/1397</li>
<li>https://github.com/rust-lang/rust/issues/17027</li>
<li>https://github.com/rust-lang/unsafe-code-guidelines/issues/176</li>
</ul>

</main>

Expand Down
32 changes: 32 additions & 0 deletions print.html
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,38 @@ <h2 id="suffix-modifiers-if-after-returnbreakcontinue-or-after-arbitrary-stateme
statement, and only later see the <code>if</code> and realize it's a conditional return.</p>
<p>Such a change would also have non-obvious evaluation order (evaluating the
condition before the return expression).</p>
<h2 id="size--stride"><a class="header" href="#size--stride">Size != Stride</a></h2>
<p>Rust assumes that the size of an object is equivalent to the stride of an object -
this means that the size of <code>[T; N]</code> is <code>N * std::mem::size_of::&lt;T&gt;</code>. Allowing
size to not equal stride may allow objects that take up less space in arrays due
to the reuse of tail padding, and allow interop with other languages with this behavior.</p>
<p>One downside of this assumption is that types with alignment greater than their size can
waste large amounts of space due to padding. An overaligned struct such as the following:</p>
<pre><code>#[repr(C, align(512))]
struct Overaligned(u8);
</code></pre>
<p>will store only 1 byte of data, but will have 511 bytes of tail padding for a total size of
512 bytes. This tail padding will not be reusable, and adding <code>Overaligned</code> as a struct field
may exacerbate this waste as additional trailing padding be included after any other members.</p>
<p>Rust makes several guarantees that make supporting size != stride difficult in the general case.
The combination of <code>std::array::from_ref</code> and array indexing is a stable guarantee that a pointer
(or reference) to a type is convertible to a pointer to a 1-array of that type, and vice versa.</p>
<p>Such a change could also pose problems for existing unsafe code, which may assume that pointers
can be manually offset by the size of the type to access the next array element. Unsafe
code may also assume that overwriting trailing padding is allowed, which would conflict with
the repurposing of such padding for data storage.</p>
<p>While changing the fundamental layout guarantees seems unlikely, it may be reasonable to add additional
inspection APIs for code that wishes to opt into the possibility of copying smaller parts of an object
-- an API to find out that copying only bytes <code>0..1</code> of <code>Overaligned</code> is sufficient might still be
reasonable, or something <code>size_of_val</code>-like that could be variant-aware to say which bytes are sufficient
for copying a particular instance. Similarly, move-only fields may allow users to mitigate the effects
of tail or internal padding, as they can be reused due to the lack of a possible reference or pointer.</p>
<p>Cross-referencing to other discussions:</p>
<ul>
<li>https://github.com/rust-lang/rfcs/issues/1397</li>
<li>https://github.com/rust-lang/rust/issues/17027</li>
<li>https://github.com/rust-lang/unsafe-code-guidelines/issues/176</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><p>This section contains &quot;notes&quot; about the design of various proposals.
These are often just links to conversations, along with a few key
ideas and summaries. Sometimes it includes other information, such as
Expand Down
2 changes: 1 addition & 1 deletion searchindex.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion searchindex.json

Large diffs are not rendered by default.

0 comments on commit df2eb1e

Please sign in to comment.