rust 是否可以在透明结构中使用泛型类型的对齐方式?

kyks70gy  于 2023-03-30  发布在  其他
关注(0)|答案(2)|浏览(116)

我试图构建一个Rust类型,它的布局与某个泛型类型T相同,但复制了另一个类型A的对齐方式:

/// Copy the alignment of `A` (if larger than the alignment of `T`),
/// otherwise has the exact same memory layout as `T`.
#[repr(transparent)]
struct WithAlignment<T, A> {
    /// Zero-sized field with the alignment of `A`
    _alignment: [A; 0],

    /// Actual data
    data: T, 
}

然而,编译器似乎无法理解_alignment是一个大小为零的字段:

error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2
 --> src/lib.rs:4:1
  |
4 | struct WithAlignment<T, A> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2
5 |     /// Zero-sized field with the alignment of `A`
6 |     _alignment: [A; 0],
  |     ------------------ this field is non-zero-sized
...
9 |     data: T, 
  |     ------- this field is non-zero-sized

有没有什么方法可以告诉编译器_alignment字段应该与A具有相同的对齐方式,但大小为零,以适用于#[repr(transparent)]的方式?

ltskdhd1

ltskdhd11#

this issue中所述(@ChrisB指出),问题在于错误消息具有误导性:#[repr(transparent)]只能在有一个非零大小 * 或对齐方式不是1* 的字段时才能工作。在这种情况下,只有非零大小的字段,但是_alignment字段可能有一个非1的对齐方式,所以#[repr(transparent)]不能使用。
最简单的解决方法是使用#[repr(C)]。具体来说,参考指出:
ZST仍然是零大小的,尽管这不是C中的标准行为,并且明显与C++中空类型的行为相反,后者认为它们仍然应该消耗一个字节的空间。
这将导致类型具有相同的内存布局,尽管行为与#[repr(transparent)]略有不同,特别是在处理FFI时。

#[repr(C)]
struct WithAlignment<T, A> {
    /// Zero-sized field with the alignment of `A`
    _alignment: [A; 0],

    /// Actual data
    data: T, 
}
kq0g1dla

kq0g1dla2#

这是不可能的。repr(transparent)强制 Package 结构(T)的ABI与 Package 器(WithAlignment)的ABI相同。
校准是ABI合同的一部分。
以下声明已经是非法的:

#[repr(transparent, align = "128")]
struct BogusAlign(f64);

相关问题