Open DeltaF1 opened 1 year ago
I believe it does, yes.
I mean, the compiler is allowed to explode a struct into several independent scalar locations, provided the program doesn't observe the difference, and the result behaves as-if it didn't. (But this is a general rule: The compiler can do what it wants to implement your program, provided it resuls in the same observable behaviour as-if it executed it exactly as written).
struct into an array of bytes
Important caveat: transmuting to and copying specifically as [u8; SIZE]
is no good (because of padding and mumbles mumbles provenance). Doing an untyped copy with ptr::copy
[_nonoverlapping
] is essentially guaranteed to work. Copying as MaybeUninit<[u8; SIZE]>
or [MaybeUninit<u8>; SIZE]
is not strictly guaranteed to work yet, but does under even the strictest memory models considered so far.
This feels like a very silly/basic question to ask, but I'm getting hung up on "There are no other guarantees of data layout made by [the default] representation." Does Rust guarantee that turning a (Sized) default repr struct into an array of bytes (of length
std::mem::size_of::<T>()
), moving those bytes somewhere else in memory without modifying them, and then transmuting back into the original type will be correct? Assume that the new location is properly aligned to whateverstd::mem::align_of::<T>()
says it should be, and the struct doesn't contain anything exotic like a self-referential pointer.I think https://github.com/rust-lang/unsafe-code-guidelines/issues/97 is related to this question (and especially the hypothetical Array-of-Structs to Struct-of-Arrays transformation). I think I'm asking the question "what is a struct", and how much is the compiler allowed to mess with the common intuition of a struct as a group of self-contained contiguous bytes as long as the normal safe accesses to that struct produce the expected results.