Skip to content

Commit 447d945

Browse files
Erik Schillingroypat
authored andcommitted
Drop Default requirement on ByteValued
Since zeros are a valid value for any ByteValued type, we can use that instead of relying on a Default implementation (which may not be auto-derivable for some array types). Further optimizations would be possible if we would have access to a pointer value into the source data. Then we could also use ptr::copy_nonoverlapping and avoid pre-initialization altogether. But changing the API just for that seems a bit excessive. Signed-off-by: Erik Schilling <[email protected]>
1 parent ca6f1b1 commit 447d945

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- [[#266](https://github.com/rust-vmm/vm-memory/pull/266)] Derive `Debug` for several
66
types that were missing it.
7+
- [[#274]] Drop `Default` as requirement for `ByteValued`.
78

89
## [v0.13.1]
910

src/bytes.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//! data.
1313
1414
use std::io::{Read, Write};
15-
use std::mem::size_of;
15+
use std::mem::{size_of, MaybeUninit};
1616
use std::result::Result;
1717
use std::slice::{from_raw_parts, from_raw_parts_mut};
1818
use std::sync::atomic::Ordering;
@@ -31,7 +31,7 @@ use crate::volatile_memory::VolatileSlice;
3131
/// cause undefined behavior.
3232
///
3333
/// Implementing this trait guarantees that it is safe to instantiate the struct with random data.
34-
pub unsafe trait ByteValued: Copy + Default + Send + Sync {
34+
pub unsafe trait ByteValued: Copy + Send + Sync {
3535
/// Converts a slice of raw data into a reference of `Self`.
3636
///
3737
/// The value of `data` is not copied. Instead a reference is made from the given slice. The
@@ -268,7 +268,10 @@ pub trait Bytes<A> {
268268
///
269269
/// Returns an error if there's not enough data inside the container.
270270
fn read_obj<T: ByteValued>(&self, addr: A) -> Result<T, Self::E> {
271-
let mut result: T = Default::default();
271+
// SAFETY: ByteValued objects must be assignable from a arbitrary byte
272+
// sequence and are mandated to be packed.
273+
// Hence, zeroed memory is a fine initialization.
274+
let mut result: T = unsafe { MaybeUninit::<T>::zeroed().assume_init() };
272275
self.read_slice(result.as_mut_slice(), addr).map(|_| result)
273276
}
274277

0 commit comments

Comments
 (0)