You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So to be clear, I think we should keep open the option of eventually having types where the size is not a multiple of the alignment, which implies that arrays of such types will have to have stride > size.
To that end, we should declare arrays as something like: The first element is at offset 0, and the stride of the array is computed as the size of the element type rounded up to the next multiple of the alignment of the element type.
@gnzlbg remarks that we should also state explicitly that since repr(C) types have a size that is a multiple of their alignment, for them, we'll always have stride == size. This ensures FFI compatibility.
@Amanieu thanks! The plan here is not to specify that this actually happens. but to word things in a way that it can happen in the future.
That RFC points out that this interacts with [T; 3] being the same as (T, T, T). Good point. Namely, the type could differ in that the tuple collapses its trailing padding but the array might not. So we should call out that the total size of the array might be either elem_stride * N or elem_stride*(N-1) + elem_size.
Namely, the type could differ in that the tuple collapses its trailing padding but the array might not.
One of the many options that were proposed in #36 were that (T, T, T) should have the same layout as [T; 3]. Maybe we should call this out as an unresolved question (if we want to write something about arrays before that issue is resolved), or try to resolve both issues together.
That would make sense if we made a distinction between "size" vs "stride" in the language, but we don't. As is, the size has to be a multiple of the alignment and trailing padding of fields can't be repurposed because anyone with a &mut T to the field is allowed to write size_of::<T>() bytes.
@rkruppe see above for the prior discussion where I basically argue we should be forwards-compatible with a world where size and stride can be different. I don't think this is fundamentally incompatible with mutable references.
There are some hard questions around using ptr::offset for indexing, though.
Activity
RalfJung commentedon Feb 22, 2019
I expect there is little controversy here: The first element is at offset 0, the stride is the element type size.
It'd be nice to eventually have types with stride > size (avoiding padding at the end), but I am not sure if that is realistic?
gnzlbg commentedon Feb 22, 2019
I'm not sure I follow, do you mean
stride < size
?:RalfJung commentedon Feb 22, 2019
No, that makes no sense. Then elements would overlap.
In your example, a mutable reference to two neiughboring elements of
B
would overlap.I mean
RalfJung commentedon Feb 22, 2019
So to be clear, I think we should keep open the option of eventually having types where the size is not a multiple of the alignment, which implies that arrays of such types will have to have
stride > size
.To that end, we should declare arrays as something like: The first element is at offset 0, and the stride of the array is computed as the size of the element type rounded up to the next multiple of the alignment of the element type.
Amanieu commentedon Feb 22, 2019
See rust-lang/rfcs#1397.
RalfJung commentedon Feb 22, 2019
@gnzlbg remarks that we should also state explicitly that since
repr(C)
types have a size that is a multiple of their alignment, for them, we'll always havestride == size
. This ensures FFI compatibility.RalfJung commentedon Feb 22, 2019
@Amanieu thanks! The plan here is not to specify that this actually happens. but to word things in a way that it can happen in the future.
That RFC points out that this interacts with
[T; 3]
being the same as(T, T, T)
. Good point. Namely, the type could differ in that the tuple collapses its trailing padding but the array might not. So we should call out that the total size of the array might be eitherelem_stride * N
orelem_stride*(N-1) + elem_size
.gnzlbg commentedon Feb 22, 2019
One of the many options that were proposed in #36 were that
(T, T, T)
should have the same layout as[T; 3]
. Maybe we should call this out as an unresolved question (if we want to write something about arrays before that issue is resolved), or try to resolve both issues together.RalfJung commentedon Feb 22, 2019
For now I think we should just document how these decisions affect each other.
gnzlbg commentedon Mar 6, 2019
Does anybody have an example of such a type?
Layout of arrays
Layout of arrays
Layout of arrays
Layout of arrays
RalfJung commentedon Mar 6, 2019
@gnzlbg
hanna-kruppe commentedon Mar 6, 2019
That would make sense if we made a distinction between "size" vs "stride" in the language, but we don't. As is, the size has to be a multiple of the alignment and trailing padding of fields can't be repurposed because anyone with a
&mut T
to the field is allowed to writesize_of::<T>()
bytes.RalfJung commentedon Mar 6, 2019
@rkruppe see above for the prior discussion where I basically argue we should be forwards-compatible with a world where size and stride can be different. I don't think this is fundamentally incompatible with mutable references.
There are some hard questions around using
ptr::offset
for indexing, though.hanna-kruppe commentedon Mar 6, 2019
Ah, I see. I disagree, but I'll take that over to the PR.
Layout of arrays (#94)