如何获取Rust中忽略判别式的枚举大小?规避FFI库8字节Union Bug
问题:如何获取#[repr(C)]枚举内部联合体的大小?
背景
《Rust参考手册》明确,带有#[repr(C)]注解的Rust枚举等价于一个包含两个字段的C结构体:
- 第一个字段是用于存储判别式的C枚举类型
- 第二个字段是对应枚举所有变体字段的C联合体(Union)
由于某FFI互操作库存在Bug,必须避免使用内部联合体大小恰好为8字节的#[repr(C)]枚举。我希望通过静态断言在编译期就发现这类问题,但目前无法直接获取编译器生成的联合体类型大小(即忽略判别式的那部分大小)。
现有尝试的问题
以下代码尝试用std::mem::size_of判断,但结果完全不符合预期:
#[repr(C)] enum UnionSizeIs8Bytes { A(u8), B(u64), } #[repr(C)] enum UnionSizeIsNot8Bytes { A(u8), B(u16), } const _: () = { // 预期触发断言失败,但实际未失败 assert!(8 != std::mem::size_of::<UnionSizeIs8Bytes>()); // 预期不触发断言失败,但实际失败 assert!(8 != std::mem::size_of::<UnionSizeIsNot8Bytes>()); };
问题在于std::mem::size_of返回的是整个枚举的总大小(包含判别式),而非我们需要的内部联合体大小。
内容的提问来源于stack exchange,提问作者Shepmaster
相关产品推荐
相关产品推荐

