Skip to content

Commit 2b1c5b5

Browse files
committed
Use picture to explain union layout
1 parent 1fd8ac3 commit 2b1c5b5

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

reference/src/layout/unions.md

+25-16
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,36 @@ not to change until an RFC ratifies them.
88

99
### Layout of individual union fields
1010

11-
The layout of each union field is determined by its type.
12-
13-
<details><summary><b>Rationale</b></summary>
11+
When laying out an `union`, the compiler has to decide how the fields of the
12+
union are arranged. Union fields are laid out by the compiler "on top" of each
13+
other, that is, the bytes of one field might overlap with the bytes of another
14+
field - as opposed to, e.g., `struct`s, where the fields are laid out "next to"
15+
each other, such that the bytes of one field never overlap with the bytes of
16+
another field. This can be visualized as follows:
17+
18+
```rust,ignore
19+
[ P P [field0_ty] P P P P ]
20+
[ P P P P [field1_ty] P P ]
21+
[ P P P [field2_ty] P P P ]
22+
```
1423

15-
This is required to allow creating references to union fields:
24+
> **Figure: union field layout**: Each row in the picture shows the layout of
25+
> the union for each of its fields, where the square brackets `[]` depict an
26+
> array of bytes. Here, `P` is a byte of type `Pad` and `[field{i}_ty]` is the
27+
> bytes of the type of the `i`-th union field.
1628
17-
```rust
18-
# fn main() { unsafe {
19-
# #[derive(Copy, Clone)]
20-
struct T1;
21-
union U { f1: T1 }
22-
let u = U { f1: T1 };
23-
let t1: &T1 = &u.f1;
24-
// &T1 works for all references
25-
# }}
26-
```
27-
</details>
29+
The individual fields (`[field{i}_ty_]`) are blocks of fixed size determined by
30+
the field's layout. The compiler picks the offset of the fields with respect to
31+
the union and the `union` size according to certain constraints like, for
32+
example, the alignment requirements of the fields, the `#[repr]` attribute of
33+
the `union`, etc.
2834

2935
### Unions with default layout ("`repr(Rust)`")
3036

31-
**The default layout of unions is**, in general, **not specified.**
37+
The default layout of Rust unions is **unspecified**.
38+
39+
That is, there are no guarantees about the offset of the fields, whether all
40+
fields have the same offset, etc.
3241

3342
<details><summary><b>Rationale</b></summary>
3443

0 commit comments

Comments
 (0)