1
1
# Layout of Rust array types and slices
2
2
3
- ## Editor's Note
4
-
5
- Issue #176 clarified that as of this writing, Rust does not distinguish between size and stride, ie
6
- they are always equal.
7
-
8
3
## Layout of Rust array types
9
4
10
- Array types, ` [T; N] ` , store ` N ` values of type ` T ` with a constant _ stride_ .
11
- Here, _ stride_ is the distance between each pair of consecutive values within
12
- the array.
5
+ Array types, ` [T; N] ` , store ` N ` values of type ` T ` with a _ stride_ that is
6
+ equal to the size of ` T ` . Here, _ stride_ is the distance between each pair of
7
+ consecutive values within the array.
13
8
14
9
The _ offset_ of the first array element is ` 0 ` , that is, a pointer to the array
15
10
and a pointer to its first element both point to the same memory address.
@@ -26,33 +21,11 @@ guaranteed to be the same as the layout of a C array with the same element type.
26
21
> }` . Pointers to arrays are fine: ` extern { fn foo(x: * const [ T; N] ) -> * const
27
22
> [ U; M] ; }` , and ` struct` s and ` union`s containing arrays are also fine.
28
23
29
- The _ stride_ of the array is constant for all element pairs and it is computed
30
- as the _ size_ of the element type rounded up to the next multiple of the
31
- _ alignment_ of the element type.
32
-
33
24
### Arrays of zero-size
34
25
35
26
Arrays ` [T; N] ` have zero size if and only if their count ` N ` is zero or their
36
27
element type ` T ` is zero-sized.
37
28
38
- ### Special case ` stride == size `
39
-
40
- When the element _ size_ is a multiple of the element's _ alignment_ , then `stride
41
- == size` , and the elements are laid out contiguously in memory, e.g., ` [ u8; 4] `.
42
- In this case, the _ size_ of the array can be computed as ` size_of::<T>() * N ` ,
43
- and a pointer to the ` i ` -th element of the array can be obtained by offsetting a
44
- pointer to the first element of the array by ` i ` [ ^ 1 ] .
45
-
46
- > ** Note:** In the current Rust implementation, _ size_ is always a multiple of
47
- > the element's _ alignment_ , and therefore ` stride == size ` always holds. This
48
- > is, however, not guaranteed by the [ layout of structs and tuples] .
49
-
50
- [ ^ 1 ] : When ` stride > size ` the pointer needs to be advanced by the array
51
- _ stride_ instead of by the element _ size_ .
52
-
53
- [ layout of structs and tuples ] : ./structs-and-tuples.md
54
-
55
-
56
29
### Layout compatibility with packed SIMD vectors
57
30
58
31
The [ layout of packed SIMD vector types] [ Vector ] [ ^ 2 ] requires the _ size_ and
@@ -68,29 +41,3 @@ type and the same number of elements as the vector.
68
41
## Layout of Rust slices
69
42
70
43
The layout of a slice ` [T] ` of length ` N ` is the same as that of a ` [T; N] ` array.
71
-
72
- ## Unresolved questions
73
-
74
- ### Guaranteeing ` stride == size ` ?
75
-
76
- Currently, the [ layout of structs and tuples] does not guarantee that the
77
- element _ size_ is a multiple of its _ alignment_ . For example, consider:
78
-
79
- ``` rust,ignore
80
- struct A(u16, u8);
81
- type B = [A; 4];
82
- ```
83
-
84
- In the current Rust implementation, ` A ` has an alignment of ` 2 ` and a size of ` 4 ` ,
85
- and ` B ` has a size of ` 16 ` , such that ` B ` contains four ` A ` s that are contiguously
86
- laid in memory.
87
-
88
- However, a future Rust implementation could implement a layout optimization that
89
- reduces the size of ` A ` to ` 3 ` . For the elements of ` B ` to be properly aligned,
90
- ` B ` would need to choose a ` stride == 4 ` , resulting in a ` stride > size ` .
91
-
92
- Guaranteeing ` stride >= size ` is forward-compatible with such
93
- layout-optimization proposals:
94
-
95
- * [ rust-lang/rfcs/1397: Spearate size and stride for types] ( https://github.com/rust-lang/rfcs/issues/1397 )
96
- * [ rust-lang/rust/17027: Collapse trailing padding] ( https://github.com/rust-lang/rust/issues/17027 )
0 commit comments