- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在以下情况下,我正在努力思考 Rust 的别名规则:
假设我们在 C 中有一个内存分配。我们将指向该分配的指针传递给 Rust。 Rust 函数对分配做一些事情,然后回调到 C 代码(没有任何参数),其中另一个 Rust 函数使用与参数相同的分配被调用。现在,让我们假设只有第一个 Rust 函数获得可变引用。
调用堆栈如下所示:
Some C Code (owns data)
Rust(pointer as &mut)
Some C code (does not get parameters from Rust)
Rust(pointer as &)
作为一个简短的例子,我们假设有以下两个文件:测试.c
#include <stdio.h>
#include <stdlib.h>
void first_rust_function(int * ints);
void another_rust_function(const int * ints);
int * arr;
void called_from_rust() {
another_rust_function(arr);
}
int main(int argc, char ** argv) {
arr = malloc(3*sizeof(int));
arr[0]=3;
arr[1]=4;
arr[2]=53;
first_rust_function(arr);
free(arr);
}
测试.rs
use std::os::raw::c_int;
extern "C" { fn called_from_rust(); }
#[no_mangle]
pub extern "C" fn first_rust_function(ints : &mut [c_int;3]) {
ints[1] = 7;
unsafe { called_from_rust() };
}
#[no_mangle]
pub extern "C" fn another_rust_function(ints : &[c_int;3]) {
println!("Second value: {}", ints[1])
}
(为了完整起见:运行此代码会打印“第二个值:7”)
请注意,从 Rust (called_from_rust()
) 回调 C 没有任何参数。因此,Rust 编译器没有任何人可能从指向的值中读取的信息。
我的直觉告诉我这是未定义的行为,但我不确定。
我快速浏览了 Stacked Borrows,发现违反了该模型。在上面的示例中,只有 Rule (protector)
被破坏了,但是如果 first_rust_function(ints : &mut [c_int;3])
仍然会使用 ints
在调用 called_from_rust()
之后还会违反其他规则。
但是,我还没有找到任何官方文档说明 Stacked Borrows 是 Rust 编译器使用的别名模型,并且在 Stacked Borrows 下被认为未定义的所有内容实际上在 Rust 中都是未定义的。天真地,这看起来与将 &mut
强制转换为 &
非常相似,因此它实际上可能是理智的,但考虑到 called_from_rust()
不采用引用作为参数,我认为这个推理不适用。
这让我想到了实际的问题:
called_from_rust()
将指针作为参数并将其向前传递,那么行为是否定义良好:void called_from_rust(const int * i) { another_rust_function (一世); }
?&mut [c_int;3]
会怎样?最佳答案
Is the above code invoking undefined behaviour?
是的,您违反了 Rust 的指针别名规则。依赖 Stacked Borrows 规则有点可疑,因为正如您所暗示的,我认为它没有被正式采用为 Rust 的内存访问模型(即使它只是对当前语义的形式化)。然而, 一个实用而具体的规则是 LLVM 的 noalias
Rust 编译器在 &mut
上使用的属性参数。
This indicates that memory locations accessed via pointer values based on the argument or return value are not also accessed, during the execution of the function, via pointer values not based on the argument or return value. ...
既然你访问了ints[1]
在 another_rust_function
来自不基于 ints
的指针在 first_rust_function
在执行该功能期间,这是违规行为。鉴于这种未定义的行为,我相信编译器完全有权让代码打印“第二个值:4”。
Would the behaviour be well-defined if
called_from_rust()
would have the pointer as parameter and pass it forward:void called_from_rust(const int * i) { another_rust_function(i); }
?
是的,这将使它定义明确。您可以看到,因为 Rust 借用检查器可以看到该值可以在 called_from_rust()
中使用并将防止不当使用 ints
围绕那个电话。
What if both Rust functions were using
&mut [c_int;3]
?
如果您使用上面的修复方法,其中第二个借用是基于第一个,那么就没有问题。如果你不这样做,那就更糟了。
关于Rust FFI 和别名 : C -> Rust -> C -> Rust call stacks with C values being aliased: Undefined Behaviour?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70633412/
我正在努力通过接受 void 的 FFI 传递结构并在另一端读回它。 有问题的库是 libtsm,一个终端状态机。它允许您提供输入,然后找出输入后终端将处于哪种状态。 它将其绘制函数声明为: pub
只是为了测试目的,我在 delphi 中创建了一个小的 DLL。代码为: library MyDll; uses SysUtils, Classes, Vcl.Dialogs;
这是我一直好奇的事情:我想知道 LuaJIT 的 FFI 模块如何设法使用正确的调用约定来调用外部 native 函数,而无需在用户原型(prototype)中进行任何声明。 我尝试阅读源代码以自己解
我有一个带有函数的 C 库,在一个不透明的结构上运行,定义如下: Foo* makeFoo(); // create a new Foo Foo* dupFoo(const Foo* orig); /
我正在尝试从 purescript 调用 navigator.geolocation.getCurrentPosition javascript 函数,但遇到了两个问题。 在 javascript 中
ruby 版本 2.2.4p230 RubyGem 版本 2.7.2 已安装 Ruby-devel 和 lib64ffi-devel。 使用 64 位 OpenMandriva 3.0、urpmi 和
我正在尝试使用 FFI 将以下 JavaScript 函数导入 PureScript: function getGreeting() { return "Hi, welcome to the sh
我对 Haskell 中的 FFI 有一些疑问 我知道我必须使用语言编译指示 {-# LANGUAGE ForeignFunctionInterface #-}但是当我使用 {-# LANGUAGE
当我尝试构建 Flutter项目至 IOS 它向我显示了这个错误,我尝试清理并尝试更改项目的目录。 Launching lib/main.dart on iPhone 12 Pro Max in de
完整堆栈跟踪: /Users/galharth/.rvm/gems/ruby-2.3.0/gems/activesupport-4.2.5/lib/active_support/dependencie
我试过运行 pod install在我的 Xcode 项目中,但出现以下错误 /System/Library/Frameworks/Ruby.framework/Versions/2.6/us
我需要在节点 Electron 项目中使用模块“ffi”。我可以使用“gyp”重建它并在节点中使用库,但我不能使用“electron-rebuild”重建它并在 Electron 中使用它。 我跑了:
以下警告是什么意思,我该如何解决它的原因? Warning: Unimplemented primitive used:removeEventListener 在 [@bs.val] external
谁能告诉我一个使用带有可变参数的 C 函数(例如 printf )和 Haskell 的外部函数接口(interface)的示例?我尝试搜索 HaskellWiki,但没有找到这样的示例。 谢谢! 最
我使用 FFI 是为了在 C 中使用一个函数,该函数接受一个结构并返回相同的结构。我看到的引用说我必须使用指向这些结构的指针才能将其导入 Haskell。所以,例如。 data Bar = Bar {
我想在带有 FFI 的 Rust 中包含一个动态 C 库。 该库实际上也是用 Rust 构建的,但公开了一个 C 接口(interface),因此它也可以从其他语言中使用。当我用 cargo 构建库(
我试图在winapi上写一个包装器。我想包装接受回调函数指针的函数。 例如,考虑以下情况: // The unsafe callback type the FFI function accepts t
我正在使用 rust-bindgen 从 Rust 访问 C 库。一些函数返回指向结构的可空指针,bindgen 表示为 extern "C" { pub fn get_some_data()
介绍 我正在用 inline-c 包装一个 C 数值库;一些函数可以将回调传递给步骤例程,考虑 ODE 的优化或时间积分。 特别是在原生 C 中,使用回调可以对连续数组进行操作,通过指针修改它们,并将
fn main() { let val = 0; unsafe { foo(&val) } } extern "C" { pub fn foo(val: *const u32)
我是一名优秀的程序员,十分优秀!