gpt4 book ai didi

rust - 为什么Rust不允许可变别名?

转载 作者:行者123 更新时间:2023-12-03 11:38:08 25 4
gpt4 key购买 nike

Rust禁止这种代码,因为它是不安全的:

fn main() {
let mut i = 42;
let ref_to_i_1 = unsafe { &mut *(&mut i as *mut i32) };
let ref_to_i_2 = unsafe { &mut *(&mut i as *mut i32) };

*ref_to_i_1 = 1;
*ref_to_i_2 = 2;
}

如何使用对同一事物的多个可变引用来做不好的事情(例如,段错误,未定义的行为等)?

我能看到的唯一可能的问题来自数据的生存期。在这里,如果 i仍然存在,则对它的每个可变引用都应该可以。

我可以看到引入线程时可能会有问题,但是为什么即使我在一个线程中完成所有操作,也可以防止出现问题?

最佳答案

How can I do do something bad (e.g. segmentation fault, undefined behavior, etc.) with multiple mutable references to the same thing?


我相信,尽管您这样做会触发“未定义行为”,但从技术上讲,Rust编译器并未将 noalias标志用于 &mut引用,因此,实际上,目前来说,您实际上可能无法以这种方式触发未定义行为。您触发的是“特定于实现的行为”,即“根据LLVM的行为类似于C++”。
有关更多信息,请参见 Why does the Rust compiler not optimize code assuming that two mutable references cannot alias?

I can see how there might be problems when threads are introduced, but why is it prevented even if I do everything in one thread?


阅读 this series of blog articles about undefined behavior
在我看来,竞争条件(例如迭代器)并不是您所谈论内容的一个很好的例子。在单线程环境中,如果小心的话,可以避免此类问题。这与创建指向无效内存的任意指针并对其进行写入没有什么不同。只是不做。您不会比使用C更糟糕。
要了解此处的问题,请考虑在 Release模式下进行编译时,编译器在执行优化时可能会也可能不会对语句进行重新排序;这意味着尽管您的代码可以按线性顺序运行:
a; b; c;
不能保证编译器在运行时将按该顺序执行它们,如果(根据编译器所知道的)逻辑上没有理由必须以特定的原子顺序执行语句。我上面链接到的博客的第3部分演示了这如何导致未定义的行为。
tl; dr :基本上,编译器可以执行各种优化。当且仅当您的程序未触发未定义的行为时,这些保证可以继续使您的程序以确定性的方式运行。
据我所知,Rust编译器 目前并没有使用许多可能导致这种故障的“高级优化”,但不能保证将来不会。引入新的编译器优化并不是“重大变化”。
所以...实际上,您现在极不可能仅通过可变别名就能触发实际的未定义行为。但是这种限制允许将来进行性能优化。
相关报价:

The C FAQ defines “undefined behavior” like this:

Anything at all can happen; the Standard imposes no requirements. The program may fail to compile, or it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.

关于rust - 为什么Rust不允许可变别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66039832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com