我试图构建一个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)]
的方式?
2条答案
按热度按时间ltskdhd11#
如this issue中所述(@ChrisB指出),问题在于错误消息具有误导性:
#[repr(transparent)]
只能在有一个非零大小 * 或对齐方式不是1* 的字段时才能工作。在这种情况下,只有非零大小的字段,但是_alignment
字段可能有一个非1的对齐方式,所以#[repr(transparent)]
不能使用。最简单的解决方法是使用
#[repr(C)]
。具体来说,参考指出:ZST仍然是零大小的,尽管这不是C中的标准行为,并且明显与C++中空类型的行为相反,后者认为它们仍然应该消耗一个字节的空间。
这将导致类型具有相同的内存布局,尽管行为与
#[repr(transparent)]
略有不同,特别是在处理FFI时。kq0g1dla2#
这是不可能的。
repr(transparent)
强制 Package 结构(T
)的ABI与 Package 器(WithAlignment
)的ABI相同。校准是ABI合同的一部分。
以下声明已经是非法的: