Yes, such an initialization is required in safe Rust. The compiler isn't necessarily able to tell that the combination of read_exact
and ?
will prevent accesses to any uninitialized data from the array. The optimizing passes may make it better, but that cannot be counted on to work.
You could instead read into a Vec
, which internally guarantees to never allow access to the uninitialized memory:
fn parse<R: Read>(r: &mut R) -> io::Result<()> {
let mut buf = vec![]; // Can optionally use `Vec::with_capacity`
r.take(1024).read_to_end(&mut buf)?;
// Do things to buf
Ok(())
}
In unsafe Rust, you can use mem::uninitialized
. Make sure you understand all the terrible little nuances involved before choosing such a situation! Reading uninitialized memory is undefined behavior in Rust, so you must make absolutely sure that you prevent it from ever happening.
Here, we rely on:
- The fact that
read_exact
will return an error if it didn't populate all of the bytes.
- The fact that the destructor of
[u8; 1024]
will not read the bytes. This is important path to consider when an error occurs or if a panic is raised.
fn parse<R: Read>(r: &mut R) -> io::Result<()> {
unsafe {
let mut buf: [u8; 1024] = mem::uninitialized();
r.read_exact(&mut buf)?;
// Do things to buf
}
Ok(())
}
I wouldn't think this is would be worth it without heavy profiling.