- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在与 MaybeUninit
做一些事情和 Rust 中的 FFI 似乎有效,但我怀疑可能不健全/依赖于未定义的行为。
我的目标是拥有一个结构 MoreA
扩展结构 A
, 包括 A
作为初始字段。然后调用一些写入结构体的 C 代码 A
.然后敲定MoreA
根据 A
中的内容填写附加字段.
在我的应用程序中,MoreA
的附加字段都是整数,所以我不必担心分配给他们的(未初始化的)以前的值。
这是一个最小的例子:
use core::fmt::Debug;
use std::mem::MaybeUninit;
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
struct A(i32, i32);
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
struct MoreA {
head: A,
more: i32,
}
unsafe fn mock_ffi(p: *mut A) {
// write doesn't drop previous (uninitialized) occupant of p
p.write(A(1, 2));
}
fn main() {
let mut b = MaybeUninit::<MoreA>::uninit();
unsafe { mock_ffi(b.as_mut_ptr().cast()); }
let b = unsafe {
let mut b = b.assume_init();
b.more = 3;
b
};
assert_eq!(&b, &MoreA { head: A(1, 2), more: 3 });
}
let b = unsafe { ... }
声音?它运行正常,
Miri doesn't complain .
MaybeUninit
docs说:
Moreover, uninitialized memory is special in that the compiler knows that it does not have a fixed value. This makes it undefined behavior to have uninitialized data in a variable even if that variable has an integer type, which otherwise can hold any fixed bit pattern.
Producing an invalid value, even in private fields and locals. "Producing" a value happens any time a value is assigned to or read from a place, passed to a function/primitive operation or returned from a function/primitive operation. The following values are invalid (at their respective type):
... An integer (i*/u*) or ... obtained from uninitialized memory.
more
调用前的字段
assume_init
.稍后在同一页面上:
There is currently no supported way to create a raw pointer or reference to a field of a struct inside MaybeUninit. That means it is not possible to create a struct by calling MaybeUninit::uninit::() and then writing to its fields.
MoreA
中)。 A
转至 mock_ffi
然后必须将结果复制到 MoreA
. A
在我的实际应用中是一个大型结构。 MaybeUninit::zeroed()
开始而不是 MaybeUninit::uninit()
. 最佳答案
目前,引用任何类型的未初始化内存的唯一合理方法是 MaybeUninit
.实际上,读取或写入未初始化的整数可能是安全的,但这并没有正式记录。读取或写入未初始化的 bool
绝对不安全或大多数其他类型。
通常,如文档所述,您不能逐个字段初始化结构字段。但是,只要符合以下条件,这样做是合理的:
repr(C)
.这是必要的,因为它可以防止 Rust 做聪明的布局技巧,从而布局 MaybeUninit<T>
类型的字段。与 T
类型的字段的布局保持相同,无论其相邻字段如何。 MaybeUninit
.这让我们assume_init()
对于整个结构,然后单独初始化每个字段。 repr(C)
,您可以使用使用
MaybeIninit
的中间表示对于每个领域。
repr(C)
也意味着一旦初始化,我们就可以在类型之间进行转换,前提是两个结构具有相同顺序的相同字段。
use std::mem::{self, MaybeUninit};
#[repr(C)]
struct MoreAConstruct {
head: MaybeUninit<A>,
more: MaybeUninit<i32>,
}
let b: MoreA = unsafe {
// It's OK to assume a struct is initialized when all of its fields are MaybeUninit
let mut b_construct = MaybeUninit::<MoreAConstruct>::uninit().assume_init();
mock_ffi(b_construct.head.as_mut_ptr());
b_construct.more = MaybeUninit::new(3);
mem::transmute(b_construct)
};
关于rust - 写入 MaybeUninit 结构中的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61318595/
下面的代码好听吗? #![feature(maybe_uninit)] use std::mem; const N: usize = 2; // or another number type T =
我正在与 MaybeUninit 做一些事情和 Rust 中的 FFI 似乎有效,但我怀疑可能不健全/依赖于未定义的行为。 我的目标是拥有一个结构 MoreA扩展结构 A , 包括 A作为初始字段。然
我正在编写代码来初始化 MaybeUninit 的数组s 并在出现 panic 时删除所有已初始化的元素。 Miri 提示未定义的行为,我已将其简化为以下示例。 use std::mem::{tran
在标准库中,documentation显示如何实例化数组MaybeUninit: let arr: [MaybeUninit; N] = MaybeUninit::uninit().assum
我是一名优秀的程序员,十分优秀!