据我所知,引用/指针别名会阻碍编译器生成优化代码的能力,因为它们必须确保在两个引用/指针确实是别名的情况下,生成的二进制文件的行为正确。例如,在以下C代码中,
void adds(int *a, int *b) {
*a += *b;
*a += *b;
}
Run Code Online (Sandbox Code Playgroud)
当clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)用-O3标志编译时,它发出
0000000000000000 <adds>:
0: 8b 07 mov (%rdi),%eax
2: 03 06 add (%rsi),%eax
4: 89 07 mov %eax,(%rdi) # The first time
6: 03 06 add (%rsi),%eax
8: 89 07 mov %eax,(%rdi) # The second time
a: c3 retq
Run Code Online (Sandbox Code Playgroud)
下面的代码存回(%rdi)两次的情况下,int *a和int *b别名。
当我们明确告诉编译器这两个指针不能使用restrict关键字别名时:
void adds(int * restrict a, int * restrict …Run Code Online (Sandbox Code Playgroud) 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;
}
Run Code Online (Sandbox Code Playgroud)
如何通过对同一事物的多个可变引用来做一些不好的事情(例如,分段错误,未定义的行为等)?
我能看到的唯一可能的问题来自数据的生命周期.在这里,如果i是活着的,每个可变引用都应该没问题.
我可以看到引入线程时可能会出现什么问题,但是为什么即使我在一个线程中执行所有操作也会阻止它?
根据文档,
\n\n\n数据竞争会导致未定义的行为,并且当您\xe2\x80\x99尝试在运行时追踪它们时,可能很难诊断和修复;Rust 通过拒绝编译带有数据竞争的代码来防止这个问题!
\n
除非你\xe2\x80\x99re多线程,否则为什么这是一个问题?如果同时访问一个变量及其一个mut引用,\xe2\x80\x99t 这个问题是否仍然存在?