mem::align_of() 与 mem::align_of_val() 函数

这一组函数用于获取类型的内存对齐大小.

其差别在于:

  • align_of() 获取某个类型的对齐大小
  • align_of_val() 获取某个值所属类型的对齐大小

它们的函数接口如下:

#![allow(unused)]
fn main() {
pub const fn align_of<T>() -> usize;
pub fn align_of_val<T>(val: &T) -> usize where T: ?Sized;
}

下面是一个基本的用例:

#![allow(non_camel_case_types)]

use std::mem::align_of;

// rustc 决定内存布局
pub struct linux_dirent_t {
    pub d_ino: u64,
    pub d_off: u64,
    pub d_reclen: u16,
    pub d_type: u8,
    pub d_name: *mut u8,
}

// 使用 C ABI 兼容的内存布局
#[repr(C)]
pub struct linux_dirent_c_t {
    pub d_ino: u64,
    pub d_off: u64,
    pub d_reclen: u16,
    pub d_type: u8,
    pub d_name: *const u8,
}

// 为结构体添加 packed attribute, 忽略结构体内成员的内存对齐.
#[repr(C, packed)]
pub struct linux_dirent_packed_t {
    pub d_ino: u64,
    pub d_off: u64,
    pub d_reclen: u16,
    pub d_type: u8,
    pub d_name: *const u8,
}

#[repr(C, packed(2))]
pub struct linux_dirent_packed2_t {
    pub d_ino: u64,
    pub d_off: u64,
    pub d_reclen: u16,
    pub d_type: u8,
    pub d_name: *const u8,
}

#[repr(C, align(16))]
pub struct linux_dirent_align_t {
    pub d_ino: u64,
    pub d_off: u64,
    pub d_reclen: u16,
    pub d_type: u8,
    pub d_name: *const u8,
}


fn main() {
    assert_eq!(align_of::<linux_dirent_t>(), 8);
    assert_eq!(align_of::<linux_dirent_c_t>(), 8);
    assert_eq!(align_of::<linux_dirent_packed_t>(), 1);
    assert_eq!(align_of::<linux_dirent_packed2_t>(), 2);
    assert_eq!(align_of::<linux_dirent_align_t>(), 16);
}

参考