首页 > 解决方案 > 一致地对齐 void 指针

问题描述

gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

如何以一致的方式将void * 没有声明类型的引用实体与缓存行大小对齐?

我有兴趣用 Standard 解释通用对齐技术的合法性。

我的尝试

void *ptr = //some valid pointer;
void *aligned_ptr = (void *) ((intptr_t) ptr & -64);

(intptr_t) ptr & -64部分符合要求,因为 any 7.20.1.4 N2310

无符号整数类型,其属性是任何指向 void 的有效指针都可以转换为此类型,然后转换回指向 void 的指针,结果将与原始指针进行比较

转换(intptr_t) ptr & -64void *未指定具有明确定义的行为。6.3.2.3/5提供了一些模糊的信息(emp. mine):

整数可以转换为任何指针类型。除非前面指定,结果是实现定义的可能未 正确对齐可能不指向引用 类型的实体,并且可能是陷阱表示

如果我正确理解“陷阱表示”的概念,那么在这种情况下就不可能拥有它,因为没有声明对象的类型。

我不确定(void *) ((intptr_t) ptr & -64)从标准的角度来看是否正确对齐,或者结果不是定义的实现。

UPD:6.2.8描述

每个有效的对齐值应是 2 的非负整数幂。

因为_Alignof (max_align_t)16我的实现中,所以我认为 64 字节对齐没有义务得到 gcc 的支持。

标签: cpointersgccalignmentlanguage-lawyer

解决方案


如果你真的想要一个通用的解决方案,也许可以使用union和可选的一些预处理器宏。

union myptr{
    void *ptr;
    (whatever-type-that-meets-your-padding-requirment) padding;
};

union myptr myalignedptr;
#define alignedptr (myalignedptr.ptr)       /* optional */

推荐阅读