我如何通过对同一事物的多个可变引用来做坏事(例如分段错误、未定义的行为等)?
我相信,尽管这样做会触发"未定义的行为",但technically Rust编译器不会对&mut
个引用使用noalias
标志,所以practically说,现在,你可能无法通过这种方式触发未定义的行为.触发的是"实现特定行为",它的行为类似于LLVM的C++.
更多信息请参见Why does the Rust compiler not optimize code assuming that two mutable references cannot alias?.
我可以看出当引入线程时可能会出现问题,但为什么即使我在一个线程中完成所有操作,也会被阻止呢?
读this series of blog articles about undefined behavior
在我看来,竞争条件(比如迭代器)并不是你所说的一个很好的例子;在单线程环境中,如果小心,可以避免此类问题.这和创建一个指向无效内存的任意指针并写入它没有什么不同;别这么做.你的情况并不比使用C更糟.
为了理解这里的问题,考虑在发布模式编译时,编译器在执行优化时可以或可能不重新排序语句;这意味着,尽管代码可能以线性顺序运行:
a; b; c;
如果(根据编译器知道的情况)没有逻辑上的理由说明这些语句必须按特定的原子顺序执行,则无法保证编译器在运行时会按该顺序执行它们.我在上面链接的博客的第3部分演示了这如何会导致未定义的行为.
tl;dr:基本上,编译器可以执行各种优化;这些保证会继续使您的程序以确定性的方式运行if and only if您的程序不会触发未定义的行为.
据我所知,Rust compiler currently没有使用许多可能导致此类故障的"高级优化",但不能保证将来不会.引入新的编译器优化并不是一个"突破性的改变".
所以实际上,你现在很可能不太可能仅仅通过可变别名触发实际的未定义行为;但这种限制允许将来进行性能优化.
相关引用:
C FAQ对"未定义行为"的定义如下:
任何事情都有可能发生;该标准没有规定任何要求.程序可能无法编译,或者可能执行不正确(崩溃或默默地生成错误的结果),或者它可能意外地完全按照程序员的意图执行.