我的直觉对移动和复制肯定是错误的.我希望Rust编译器将不可变值的移动优化为无操作.由于该值是不可变的,因此我们可以在移动后安全地重用它.但是Rust 1.65.0 on Godbolt编译成程序集,将值复制到内存中的新位置.我正在研究的铁 rust 代码:

pub fn f_int() {
    let x = 3;
    let y = x;
    println!("{}, {}", x, y);
}

生成的部件具有-C opt-level=3:

    ; pub fn f_int() {
    sub     rsp, 88
    ; let x = 3;
    mov     dword ptr [rsp], 3
    ; let y = x;
    mov     dword ptr [rsp + 4], 3
    mov     rax, rsp
    ...

为什么let y = x;等于mov dword ptr [rsp + 4], 3mov rax, rsp?为什么编译器不将y视为与程序集中的x相同的变量?

(This question看起来很相似,但它是关于不是复制的字符串.我的问题是关于复制的整数.看起来我所描述的并不是一个错失的优化机会,而是我理解上的一个根本错误.)

推荐答案

我不认为这是你理解中的一个根本性错误,但这里有一些有趣的观察.

首先,由于其设计原因,println!()(尤其是格式化机制)很难优化.因此,在println!()个版本中没有优化也就不足为奇了.

第二,it is generally not obvious it is OK to perform this optimization, because it observably make the addresses equivalent.println!()获取打印值的地址(并将它们传递给不透明函数).事实上,在这一点上,Copy类型比非Copy类型更难调整,因为对于Copy类型,在移动之后可能仍然使用原始变量,而对于非Copy类型it is possible that not,可能仍然使用原始变量.

Rust相关问答推荐

交叉术语未正确清除屏幕

为什么类型需要在这个代码中手动指定,在rust?

如何装箱生命周期相关联的两个对象?

如何删除Mac Tauri上的停靠图标?

关于 map 闭合求和的问题

为什么AsyncRead在Box上的实现有一个Unpin特征绑定?

为什么 GAT、生命周期和异步的这种组合需要 `T: 'static`?

使用 select 处理 SIGINT 和子等待!无阻塞

使用 Option 来分配?

需要一个有序向量来进行 struct 初始化

为什么这个闭包没有实现Fn?

通过mem::transmute将数组展平安全吗?

如何在 Rust 中按 char 对字符串向量进行排序?

如何在 Emacs Elisp 中获得类似格式化的 LSP?

如何获取函数中borrow 的切片的第一部分?

在异步 Rust 中,Future 如何确保它只调用最近的 Waker?

Rust,我如何正确释放堆分配的内存?

在空表达式语句中移动的值

如何将 u8 切片复制到 u32 切片中?

在特征中返回一个 Self 类型的值