Code
I tried this code:
use std::mem::MaybeUninit;
#[repr(C)]
pub struct X {
a : u16,
b : u8,
c : u32
}
#[unsafe(no_mangle)]
pub fn bad(a: &mut [MaybeUninit<u32>;2]) {
let x = X { a : 0, b : 0, c : 0};
unsafe {
std::ptr::write((&raw mut *a).cast::<X>(), x)
}
}
#[unsafe(no_mangle)]
pub fn bad_too(a: &mut MaybeUninit<X>) {
let x = X { a : 0, b : 0, c : 0};
unsafe {
std::ptr::write(a.as_mut_ptr(), x)
}
}
#[unsafe(no_mangle)]
pub fn not_bad(a: &mut MaybeUninit<X>) {
let x = X { a : 0, b : 0, c : 0};
a.write(x);
}
I expected to see this happen: each function would result in either 2 4-byte stores of 0 or one 8-byte store of 0 dependinding on how the compiler deals with the alignement.
what happened :
bad:
mov word ptr [rdi], 0
mov byte ptr [rdi + 2], 0
mov dword ptr [rdi + 4], 0
ret
not_bad:
mov qword ptr [rdi], 0
ret
bad_too = bad
both bad and bad_too avoided writing the padding byte, even though there is no reason for them to do so.
this has been the case since 1.81 when MaybeUninit::write was stabilized
godbolt link ; https://godbolt.org/z/Yj6GWhebq
this might be an llvm issue, but i gigured it might be best to ask here first
Code
I tried this code:
I expected to see this happen: each function would result in either 2 4-byte stores of 0 or one 8-byte store of 0 dependinding on how the compiler deals with the alignement.
what happened :
both
badandbad_tooavoided writing the padding byte, even though there is no reason for them to do so.this has been the case since
1.81whenMaybeUninit::writewas stabilizedgodbolt link ; https://godbolt.org/z/Yj6GWhebq
this might be an llvm issue, but i gigured it might be best to ask here first