Re:Writing into Uninitialized Buffers in Rust
by Arnavion on Wednesday May 21, 2025 @01:06AM
(#44048456)
No. The correct way to write that code is to use .spare_capacity_mut() to get a &mut [MaybeUninit<T>], then write your Ts into that using .write_copy_of_slice(), then .set_len(). And that will not be any slower (though obviously more complicated) than the original incorrect code.
Re:Writing into Uninitialized Buffers in Rust
by vgatherps on Wednesday May 21, 2025 @02:11AM
(#44048735)
Oh this is very nice, I think it was stabilized since I wrote said code.
Re:Writing into Uninitialized Buffers in Rust
by nemothekid on Wednesday May 21, 2025 @02:22AM
(#44048797)
write_copy_of_slice doesn't look to be stable. I'll mess around with godbolt, but my hope that whatever incantation is used compiles down to a memcpy
Re:Writing into Uninitialized Buffers in Rust
by Arnavion on Wednesday May 21, 2025 @02:33AM
(#44048849)
As I wrote in https://news.ycombinator.com/item?id=44048391 , you have to get used to copying the libstd impl when working with MaybeUninit. For my code I put a "TODO(rustup)" comment on such copies, to remind myself to revisit them every time I update the Rust version in toolchain.toml
Re:Writing into Uninitialized Buffers in Rust
by nemothekid on Wednesday May 21, 2025 @04:11AM
(#44049347)
In other words the """safe""" stable code looks like this:
let mut data = Vec::with_capacity(sz);
let mut dst_uninit = data.spare_capacity_mut();
let uninit_src: &[MaybeUninit<T>] = unsafe { transmute(buf) };
dst_uninit.copy_from_slice(uninit_src);
unsafe { data.set_len(sz) };
It’s strictly more complicated and slower than the obvious thing to do and only exists to satisfy the abstract machine.