Comments (13)
Yeah, then that's kinda dumb but also means i gotta fix the docs.
from bytemuck.
size == stride for all current rust types because size is always a multiple of alignment in current rust.
Rust could do any future change that would break a lot of people, but I'm not afraid of that happening.
particularly, since there's no stride_of
, it's impossible to design around that idea.
Basically the UCG text is trying to keep open a door that's almost for sure already closed.
from bytemuck.
While it's true that this door is almost surely closed it seems nevertheless important to list it for now. Probably a short amendment of the last requirement would do. The example above needs to abuse repr(packed)
to allow smuggle a repr(rust)
type trough the wording of the documentation. It might just take a small clarification here.
from bytemuck.
which example with a repr rust type?
from bytemuck.
This following type would adhere to the requirements in the documentation if rust tuples would be defined to have size that is not a multiple of the alignment, which currently they could be change in the future. Let's check them one-by-one.
#[repr(packed)] // Note: *composes* with the base repr, this is not repr(C) but repr(rust)
struct Bad(u16, u8);
-
The type must be inhabited (eg: no Infallible).
Obviously true. -
The type must allow any bit pattern (eg: no bool or char, which have illegal bit patterns).
Also true. -
The type must not contain any padding bytes, either in the middle or on the end (eg: no #[repr(C)] struct Foo(u8, u16), which has padding in the middle, and also no #[repr(C)] struct Foo(u16, u8), which has padding on the end).
This is the assumption, that Rust might one day enable this. In the current compiler it does not occur and the struct has padding at the end. But since it is
repr(rust)
this is not guaranteed and if a future version would stabilize this with size3
then this could be fulfilled. -
The type needs to have all fields also be Pod.
Also true. -
The type needs to be repr(C), repr(transparent), or repr(packed).
Indeed it is. I assume the documentation was intended to instead allowrepr(packed)
only in conjuction with one of the other base representations. However, it can be used onrepr(rust)
, the default.
from bytemuck.
oh so packed and C,packed are different?
from bytemuck.
oh so packed and C,packed are different?
Indeed, so it seems in the documentation.
from bytemuck.
I'm not quite sure if you actually need to mention the explicit repr(C)
requirement. More, since repr(transparent)
relies on the representation of the underlying type one could argue that this enables the same kinds of shenanigans. Rather, I would explicitely state the stride/size requirement as above and make a sidenote that this is impossible to guarantee except by explicitly annotating the type with repr(C)
or a transparent representation on top of such a type. (Apart for special exceptions such as Option<NonZeroU8>
which is neither but it has the same representation as a repr(C)
type so it's fine).
from bytemuck.
aside from stride/size, it must be C and not Rust because Rust allows field re-ordering
from bytemuck.
aside from stride/size, it must be C and not Rust because Rust allows field re-ordering
How are internal fields a problem to Pod
? That would be the problem of the programmer applying it and using it for field initialization. But a repr-packed-rust struct is guaranteed to remain padding free even if Rust is allowed to re-order the fields.
from bytemuck.
Partly for sanity sake, if a struct has fields a and b written in that order in the source, then you cast it to an array, then arr[0] better be the a
value.
But mostly I was told that it's just plain UB to, for example, cast &(u16,u16) into &[u16;2], that's just the rules. You cannot inspect or interact with the internals of repr rust except through the proscribed safe ways.
from bytemuck.
If fields were to change order, that would be very surprising (though not UB if one is very, very careful). As far as I've understood there is not even a true commitment that all instances of a particular repr-rust struct have the same order of fields? But the tuple-vs-array example, as far as I am aware, came up initially because no layout of tuples have been specified and they might still have different alignment or padding than arrays so that unconditionally casting one to the other is unsound. However, that line of reasoning is different for packed structs, which tuples are not.
But I don't want to get lost in technicalities here, it will in any case be much easier to remove some requirements than it is to add them. So, the sane option is indeed to require repr(C)
for now.
from bytemuck.
Yes, Field order is fixed during compilation and all instances of a type will have the same ordering, but they don't need to match the order you see in the source code.
in other words:
struct Stuff {
a: u8,
b: u16,
c: u8,
}
In this case, rustc
is highly likely to move the u16 to the start or the end of the struct. And that's already more than I want to put up with as a user, even assuming it's not UB to transmute that (which it is).
from bytemuck.
Related Issues (20)
- Why use from_bytes when you can use pod_read_unaligned? HOT 5
- Build error on nightly-2024-02-05 HOT 1
- Bytemuck 1.14.2 does not build on stable HOT 1
- Feature request: Casting owned slices or vec, I.e. Box<[u64]> to Box<[u8]> or Vec<u64> to Vec<u8> HOT 4
- conversion from `&[u8]` to `&[T]`? HOT 4
- Allow deriving `Zeroable` for enums which are `#[repr(u32, i8, etc..)]` HOT 2
- Address safety invariants in documentation HOT 1
- No documentation for the FooBits public type generated by derive(CheckedBitPattern) HOT 1
- Casts and conversions for owned, boxed slices HOT 5
- `#[derive(TransparentWrapper)]` doesn't work with `where` clause generic bounds. HOT 1
- Unsound usages of unsafe implementation from different generics HOT 2
- Unsound usages of unsafe implementation from `[u8]` to `T` HOT 2
- impl `ZeroableInOption` for all `Zeroable`? HOT 1
- Support `f16` and `f128` under a nightly flag HOT 2
- Relax the generic requirements for `NoUninit` and `CheckedBitPattern` derives. HOT 1
- Zero-sized type (ZST) handling inconsistency between borrowed and owned slice casts. HOT 2
- Deriving `NoUninit` (and therefore `Pod`) without `repr(packed)` by asserting all fields have the same alignment
- `TransparentWrapper` docs are confusing
- `Contiguous` should be derivable for enums when only the first discriminant is an expression HOT 1
- Good Idea: safe way to transmute `Vec<Option<&Foo>>` to `Vec<&Foo>`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bytemuck.