Skip to content

Commit e96c8b9

Browse files
authored
Merge pull request rust-lang#766 from kinseytamsin/fix-repr-c-pseudocode
Fix incorrect pseudocode for #[repr(C)] struct alignment
2 parents 50213af + 5d5b233 commit e96c8b9

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

src/type-layout.md

+24-2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,19 @@ Here is this algorithm described in pseudocode.
197197

198198
<!-- ignore: pseudocode -->
199199
```rust,ignore
200+
/// Returns the amount of padding needed after `offset` to ensure that the
201+
/// following address will be aligned to `alignment`.
202+
fn padding_needed_for(offset: usize, alignment: usize) -> usize {
203+
let misalignment = offset % alignment;
204+
if misalignment > 0 {
205+
// round up to next multiple of `alignment`
206+
alignment - misalignment
207+
} else {
208+
// already a multiple of `alignment`
209+
0
210+
}
211+
}
212+
200213
struct.alignment = struct.fields().map(|field| field.alignment).max();
201214
202215
let current_offset = 0;
@@ -205,16 +218,24 @@ for field in struct.fields_in_declaration_order() {
205218
// Increase the current offset so that it's a multiple of the alignment
206219
// of this field. For the first field, this will always be zero.
207220
// The skipped bytes are called padding bytes.
208-
current_offset += field.alignment % current_offset;
221+
current_offset += padding_needed_for(current_offset, field.alignment);
209222
210223
struct[field].offset = current_offset;
211224
212225
current_offset += field.size;
213226
}
214227
215-
struct.size = current_offset + current_offset % struct.alignment;
228+
struct.size = current_offset + padding_needed_for(current_offset, struct.alignment);
216229
```
217230

231+
<div class="warning">
232+
233+
Warning: This pseudocode uses a naive algorithm that ignores overflow issues for
234+
the sake of clarity. To perform memory layout computations in actual code, use
235+
[`Layout`].
236+
237+
</div>
238+
218239
> Note: This algorithm can produce zero-sized structs. This differs from
219240
> C where structs without data still have a size of one byte.
220241
@@ -363,3 +384,4 @@ used with any other representation.
363384
[`C`]: #the-c-representation
364385
[primitive representations]: #primitive-representations
365386
[`transparent`]: #the-transparent-representation
387+
[`Layout`]: ../std/alloc/struct.Layout.html

0 commit comments

Comments
 (0)