Sometimes there is a need to send data between processes without paying the cost of serialization and deserialization. If the data is POD, the cheapest way to do that is to transmute the data to bytes, transfer them, then transmute them back. There are crates that help with this operation, such as bytemuck and zerocopy.
If a struct contains pointers to the heap, this isn't possible for obvious reasons. But another problem arises when the type contains padding. Padding is uninitialized, so constructing a &[u8]
pointing to it is UB.
If I'm in full control of the implementation of the transfer, I can solve this issue. For example, I can operate on (*mut u8; usize)
instead of slices, and the resulting transfer implementation will be sound when working on types with padding. However, if I want to utilize std
or the async ecosystem for network communication, I can no longer work with such types because all the APIs require &[u8]
.
Note that transmuting a struct with padding to bytes and sending them over the network will work in practice. While this doesn't make UB any less scary, it may lead to projects using this approach for performance reasons because there is no sound way to do the same without paying a performance penalty. And using only types without padding has severe ergonomics downsides: enums with payload are practically unusable, and talking a reference to a packed struct's field is not allowed.
How can this situation be improved? I don't think there is a fundamental reason why this can't be done in a sound way. If the underlying system calls do not actually require bytes to be initialized, it could make sense to expose unsafe pointer-based methods on high-level interfaces. Unfortunately, in this case working with wrappers such as BufWriter
or tokio's Framed
would still be unsound unless the pointer APIs are propagated all the way.
Another way to solve this would be to add a zero-cost way to freeze the bytes so that they are arbitrary but not undefined. I found this related discussion and this PR, but the current state of this is unclear.