Reputation: 744
Is there a reasonable way to zero-initialize a union
data type in Rust?
The approach mentioned by the Rust Reference works well if the user initializes the largest field in the union, but doesn't work if a smaller field is set. For example, given a type:
union TypeFromFfi {
small: u8,
medium: u64,
large: u128,
}
These don't seem to zero-initialize all of the union's memory:
let data = unsafe { TypeFromFfi { small: 0 } };
let data = unsafe { TypeFromFfi { medium: 0 } };
This seems to:
let data = unsafe { TypeFromFfi { large: 0 } };
This is as I expect, and I am hoping to avoid this approach because it requires the caller to remember the size of each field of the union.
Is there a general way to do zero-initialize a union? So far I have thought of:
let data = unsafe { std::mem::zeroed::<TypeFromFfi>() };
It seems to work, but is there something that I could be missing?
Could there be an issue with padding bytes from using std::mem::zeroed? I can't think of anything...
Upvotes: 2
Views: 1065
Reputation: 71380
std::mem::zeroed()
is the correct way. There is no problem with initializing padding bytes.
Do note however that if zero is valid for none of the possible variants it is unclear yet whether zero-initializing the union is valid. If at any bit position zero is a valid pattern for at least one of the variants everything is fine.
Also note that your union probably has to be marked #[repr(C)]
, otherwise you cannot rely on its layout (including the abovementioned zero validity).
Upvotes: 4