FFI函数可以修改未声明为可变的变量吗?

wem*_*gah 6 rust

fn main() {
    let val = 0;
    unsafe { foo(&val) }
}

extern "C" {
    pub fn foo(val: *const u32);
}
Run Code Online (Sandbox Code Playgroud)

在C中实施:

void foo(unsigned* val) { *val=1; }
Run Code Online (Sandbox Code Playgroud)

当然,我应该通过val: *mut u32,但是在我传递不可变引用的情况下会发生什么?什么编译器规则适用?是否val保持不变,即使我一个指针传递给本地变量?

Ste*_*fan 5

我会说未定义的行为:

变异不可变数据 - 即通过共享引用或let绑定所拥有的数据到达的数据),除非该数据包含在UnsafeCell<U>.

这可能包括:

  • 如果你val在FFI调用后使用它可能会忽略你所做的写操作(例如缓存寄存器中的值或由于常量传播)
  • FFI中的段错误,因为引用的内存可能是只读的
  • 来自FFI的写入可能会出现在看似无关的位置,因为编译器重用了内存并假设它具有明确定义的值
  • 更糟糕:)