FFI 函数可以修改未声明为可变的变量吗? [英] Can an FFI function modify a variable that wasn't declared mutable?

查看:43
本文介绍了FFI 函数可以修改未声明为可变的变量吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

extern "C" {
    pub fn foo(val: *const u32);
}

在 C 中实现:

void foo(unsigned* val) { *val=1; }

当然,我应该传递val: *mut u32,但是如果我传递了一个不可变的引用,会发生什么?哪些编译器规则适用?即使我传递了一个指向局部变量的指针,val 是否保持不变?

Of course, I should pass val: *mut u32, but what happens in the case that I pass an immutable reference? What compiler rules apply? Does val remain unchanged even though I'm passing a pointer to the local variable?

推荐答案

我想说 未定义行为:

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

Mutating non-mutable data — that is, data reached through a shared reference or data owned by a let binding), unless that data is contained within an UnsafeCell<U>.

这可能包括:

  • 如果您在 FFI 调用后使用 val,它可能会忽略您所做的写入(例如将值缓存在寄存器中或由于 不断传播)
  • FFI 中的段错误,因为引用的内存可能是只读的
  • 来自 FFI 的写入可能会出现在看似无关的位置,因为编译器重用了内存并假设它具有明确定义的值
  • 更糟:)
  • if you use val after the FFI-call it might ignore the writes you did (e.g. cached the value in a register or due to constant propagation)
  • segfault in FFI because the referenced memory might be read-only
  • the write from FFI might show up in seemingly unrelated locations because the compiler reused the memory and assumed it had a well-defined value
  • and worse :)

这篇关于FFI 函数可以修改未声明为可变的变量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆