【问题标题】:How to implement the C flexible array member pattern in Rust?如何在 Rust 中实现 C 灵活数组成员模式?
【发布时间】:2018-06-23 22:47:33
【问题描述】:

我想在 Rust 中实现这个使用 flexible array member(有时称为 the struct hack)的 C 代码:

struct test {
  int key;
  int dataSize;
  int data[];
};
struct test* t = malloc(sizeof(struct test) + sizeOfData)

结构末尾的空数组允许您一次分配所有元字段和数据。不幸的是,我不知道如何在 Rust 中做这样的事情。

【问题讨论】:

  • 我认为你可以在每晚使用分配器 API 和相当数量的 unsafe 来实现这一点。但我对它在 C 中的工作方式还不够熟悉。如果data 数组的对齐大于标头的大小怎么办——是在sizeof 中计算的填充字节,还是我们只是依靠malloc 分配超出了满足最大可能对齐的必要部分?
  • @MatthieuM。可能是我的错,因为你无法避免像我说的那样填充字节,sizeof 和 offsetof 必须为 FAM 产生相同的大小。

标签: struct rust


【解决方案1】:

这个结构的 Rust 等价物将使用切片:

struct test {
  key: i32,
  dataSize: i32,
  data: [i32],
}

但是,这些类型目前使用起来并不方便,因为没有安全的方法来构造它们。

更实用的方法是使用泛型:

struct test<T: ?Sized> {
  key: i32,
  dataSize: i32,
  data: T,
}

然后确保仅在 T 是数组或切片(只能通过强制创建)时使用 test

另见:

【讨论】:

  • 不,这是错误的,切片包含它们的 len,FAM 没有。 Rust ATM 中没有 FAM 等价物。
  • @Stargateur [T] 不包含长度。你说的是&amp;[T],它是一个指向切片的胖指针:包含长度。但不是大小不一的[T] 本身。
  • @JL2210 胖指针是一个指针 + 一些额外的数据,例如 &amp;[T] 是一个胖指针,因为它包含第一个元素的地址 + 大小,&amp;dyn Trait 是一个胖指针,因为它包含一个指向数据的指针 + 一个指向 vtable 的指针。
  • @LukasKalbertodt 但这在 Rust 中没有意义,[T] 需要以某种方式知道它的大小,如果你需要不安全,这对我来说不是 Rust。说 [T] 相当于 FAM 对我来说是错误的,至少现在是这样。
  • 喂! this 能否成为所有这一切的正确解决方案?至少指向具有 extern 类型作为最后一个字段的结构的指针不是胖指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
相关资源
最近更新 更多