断言指针与某个值对齐

Assert that a pointer is aligned to some value

是否有保证方法可以断言给定的原始指针与某个对齐值对齐?

我查看了 pointer 的 aligned_offset 函数,但是文档声明允许它给出假阴性(总是 return usize::MAX),并且正确性不能依赖于它。

我根本不想 fiddle 对齐,我只是想写一个断言,如果指针未对齐,它会出现恐慌。我的动机是,当使用某些低级 CPU 内在函数传递一个未与某些边界对齐的指针时,会导致 CPU 错误,我宁愿收到一条 Rust 恐慌消息,指出导致它的错误所在位于 SEGFAULT 之外。

一个示例断言(根据 aligned_offset 文档不正确):

#[repr(align(64))]
struct A64(u8);

#[repr(align(32))]
struct A32(u8);

#[repr(align(8))]
struct A8(u8);

fn main() {
    let a64 = [A64(0)];
    let a32 = [A32(0)];
    let a8 = [A8(0), A8(0)];
    
    println!("Assert for 64 should pass...");
    assert_alignment(&a64);
    println!("Assert for 32 should pass...");
    assert_alignment(&a32);
    
    println!("Assert for 8, one of the following should fail:");
    println!("- full array");
    assert_alignment(&a8);
    println!("- offset by 8");
    assert_alignment(&a8[1..]);
}

fn assert_alignment<T>(a: &[T]) {
    let ptr = a.as_ptr();
    
    assert_eq!(ptr.align_offset(32), 0);
}

Rust playground.

为了满足自己的神经病,我去查看了ptr::align_offsetthe source

围绕边缘情况有很多仔细的工作(例如 const-总是评估它 returns usize::MAX,类似于指向 zero-sized 类型的指针,并且如果 alignment 不是 2 的幂,它会恐慌)。但是,为了您的目的,实施的关键是 here:检查它是否对齐需要 (ptr as usize) % alignment == 0

Edit: This PR is adding a ptr::is_aligned_to function, which is much more readable and also safer and better reviewed than simply (ptr as usize) % alginment == 0 (though the core of it is still that logic).

然后计算准确的偏移量会更加复杂(这可能是不可能的),但这与这个问题无关。

因此:

assert_eq!(ptr.align_offset(alignment), 0);

对于您的断言应该足够了。

顺带一提,这证明当前的rust标准库不能针对任何不将指针表示为简单数字地址的东西,否则这个函数将无法运行。在 rust 标准库被移植到 Intel 8086 或一些不以预期方式表示指针的奇怪 DSP 的不太可能的情况下,这个函数将不得不改变。不过说真的,你真的那么在乎那个假设吗?