当我使用rustc 1.rs编译下面的代码时,它会像预期的那样无休止地运行.

use std::thread;

fn main() {
    thread::spawn(|| {
        let a = 2;
        loop {
            a*a;
        }
    }).join();
}

简短的版本:

use std::thread;

fn main() {
    thread::spawn(|| {
        loop {}
    }).join();
}

但是,如果我用rustc -O 1.rs来编译上面的两个程序,它们会崩溃:

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 0, message: "Success" } }', src/libcore/result.rs:837
stack backtrace:
1:     0x5650bd0acada - std::sys::imp::backtrace::tracing::imp::write::h917062bce4ff48c3
                        at /build/rustc-1.14.0+dfsg1/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
2:     0x5650bd0b068f - std::panicking::default_hook::{{closure}}::h0bacac31b5ed1870
                        at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:247
3:     0x5650bd0aee7c - std::panicking::default_hook::h5897799da33ece67
                        at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:263
4:     0x5650bd0af4d7 - std::panicking::rust_panic_with_hook::h109e116a3a861224
                        at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:451
5:     0x5650bd0af364 - std::panicking::begin_panic::hbb38be1379e09df0
                        at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:413
6:     0x5650bd0af289 - std::panicking::begin_panic_fmt::h26713cea9bce3ab0
                        at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:397
7:     0x5650bd0af217 - rust_begin_unwind
                        at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:373
8:     0x5650bd0e2f3d - core::panicking::panic_fmt::hcfbb59eeb7f27f75
                        at /build/rustc-1.14.0+dfsg1/src/libcore/panicking.rs:69
9:     0x5650bd0a6e84 - core::result::unwrap_failed::h15a0fc826f4081f4
10:     0x5650bd0b7ffa - __rust_maybe_catch_panic
                        at /build/rustc-1.14.0+dfsg1/src/libpanic_unwind/lib.rs:97
11:     0x5650bd0a6fc1 - <F as alloc::boxed::FnBox<A>>::call_box::he32a93ebea7bc7ad
12:     0x5650bd0ae6c4 - std::sys::imp::thread::Thread::new::thread_start::ha102a6120fc52763
                        at /build/rustc-1.14.0+dfsg1/src/liballoc/boxed.rs:605
                        at /build/rustc-1.14.0+dfsg1/src/libstd/sys_common/thread.rs:21
                        at /build/rustc-1.14.0+dfsg1/src/libstd/sys/unix/thread.rs:84
13:     0x7fc2d0042423 - start_thread
14:     0x7fc2cfb6e9be - __clone
15:                0x0 - <unknown>

如果我删除了闭包中的所有代码,它将无误退出:

use std::thread;

fn main() {
    thread::spawn(|| {
    }).join();
}

如果我在循环中添加println!(),它也可以正常工作:

use std::thread;

fn main() {
    thread::spawn(|| {
        loop {
            println!("123")
        }
    }).join();
}

我在Rust 1.14和1.15上进行了测试,这两个版本都出现了相同的问题.

这是因为我使用了错误的东西还是一个错误?

推荐答案

这是known issue (#28728)美元.简而言之,LLVM优化了have no observable side-effects个循环:

实现可能会假设任何线程最终都会执行一个任务

  • 终止
  • 调用库I/O函数
  • 访问或修改易失性对象,或
  • 执行同步操作或原子操作

在这里的例子中,这些都不起作用,所以LLVM完全删除了循环.但是,Rust编译器生成的代码假定循环永远不会返回.这种不匹配会导致崩溃.

因为拥有一个没有副作用的无限循环基本上是无用的,所以这个问题是not of critical priority.铁 rust 队目前waiting for LLVM to provide a better solution人.

作为一种解决方法,您只需在循环中做一些事情,这可能是您无论如何都想做的事情^_^

Rust相关问答推荐

为什么Tauri要修改被调用函数的参数名称?

有没有方法处理rust中嵌套的ok_or()?

捕获Rust因C++异常而产生panic

为什么我们不能通过指针算法将Rust原始指针指向任意地址?'

泛型属性比较

如何在Bevy/Rapier3D中获得碰撞机的计算质量?

这是不是在不造成嵌套的情况下从枚举中取出想要的变体的惯用方法?

Rust&;Tokio:如何处理更多的信号,而不仅仅是SIGINT,即SIGQUE?

使用 pyo3 将 Rust 转换为 Python 自定义类型

如何返回 struct 体中向量的切片

当推送到 HashMap 中的 Vector 时,类型 `()` 无法取消引用

当在lambda中通过引用传递时,为什么会出现终身/类型不匹配错误?

是否可以通过可变引用推进可变切片?

简单 TCP 服务器的连接由对等重置错误,mio 负载较小

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

为什么不可变特征的实现可以是可变的?

如何将这些测试放在一个单独的文件中?

Rust 引用元组和引用元组

在 Rust 中返回对枚举变体的引用是个好主意吗?

Rust 跨同一文件夹中文件的可见性