Surprising struct copy
⚓ Rust 📅 2025-09-09 👤 surdeus 👁️ 8I was exploring various constructs and looking at the generated code. I was surprised by this
struct Foo {
x: i32,
y: i32,
arr: [i32; 50],
}
#[inline(never)]
fn print(foo: &Foo) {
println!("x: {}, y: {}", foo.x, foo.y);
}
fn main() {
let f1 = Foo {
x: 42,
y: 24,
arr: [0; 50],
};
// f1.x = 10;
print(&f1);
let f2 = f1;
// f2.x = 20;
print(&f2);
}
it generates
push rsi
.seh_pushreg rsi
push rdi
.seh_pushreg rdi
sub rsp, 456
.seh_stackalloc 456
.seh_endprologue
xorps xmm0, xmm0
movaps xmmword ptr [rsp + 208], xmm0
movaps xmmword ptr [rsp + 192], xmm0
movaps xmmword ptr [rsp + 176], xmm0
movaps xmmword ptr [rsp + 160], xmm0
movaps xmmword ptr [rsp + 144], xmm0
movaps xmmword ptr [rsp + 128], xmm0
movaps xmmword ptr [rsp + 112], xmm0
movaps xmmword ptr [rsp + 96], xmm0
movaps xmmword ptr [rsp + 80], xmm0
movaps xmmword ptr [rsp + 64], xmm0
movaps xmmword ptr [rsp + 48], xmm0
movaps xmmword ptr [rsp + 32], xmm0
mov qword ptr [rsp + 224], 0
movabs rax, 103079215146
mov qword ptr [rsp + 232], rax
lea rsi, [rsp + 32]
mov rcx, rsi
call test1::print
lea rdi, [rsp + 248]
mov r8d, 208
mov rcx, rdi
mov rdx, rsi
call memcpy
mov rcx, rdi
call test1::print
nop
add rsp, 456
pop rdi
pop rsi
ret
It treats
let f2 = f1;
the same way c does, bit blits the struct to a new copy. I expected to see move semantics, in effect making the assignment a no-op and just modifying the compile time symbol table to make f2 refer to the same stack data (given that f1 is no longer usable in any way)
2 posts - 2 participants
🏷️ Rust_feed