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
部分符合标准,因为任何7.20.1.4 N2310
:
无符号整数类型,具有任何有效指针都可以指向的属性 可以将void转换为此类型,然后将其转换回指向 void,结果将等于原始指针
未指定将(intptr_t) ptr & -64
转换回void *
具有明确定义的行为。 6.3.2.3/5
提供了一些模糊的信息(临时矿):
整数可以转换为任何指针类型。除了以前 指定,结果是实现定义的,可能不是 正确对齐,可能未指向所引用的实体 类型,并且可能是陷阱表示。
如果我正确理解了“陷阱表示”的概念,则由于没有声明对象的类型,因此在这种情况下是不可能的。
从标准的角度来看,我不确定(void *) ((intptr_t) ptr & -64)
是否正确对齐,或者结果是否未定义实现。
UPD:6.2.8
描述
每个有效对齐值均应为的非负整数幂 两个。
由于在我的实现中_Alignof (max_align_t)
是16
,所以我认为gcc不支持64字节对齐。
答案 0 :(得分:1)
如果您确实需要通用解决方案,则可以使用union
和某些预处理器宏。
union myptr{
void *ptr;
(whatever-type-that-meets-your-padding-requirment) padding;
};
union myptr myalignedptr;
#define alignedptr (myalignedptr.ptr) /* optional */