c - 一致地对齐 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 & -64
回void *
未指定具有明确定义的行为。6.3.2.3/5
提供了一些模糊的信息(emp. mine):
整数可以转换为任何指针类型。除非前面指定,结果是实现定义的,可能未 正确对齐,可能不指向引用 类型的实体,并且可能是陷阱表示。
如果我正确理解“陷阱表示”的概念,那么在这种情况下就不可能拥有它,因为没有声明对象的类型。
我不确定(void *) ((intptr_t) ptr & -64)
从标准的角度来看是否正确对齐,或者结果不是定义的实现。
UPD:6.2.8
描述
每个有效的对齐值应是 2 的非负整数幂。
因为_Alignof (max_align_t)
在16
我的实现中,所以我认为 64 字节对齐没有义务得到 gcc 的支持。
解决方案
如果你真的想要一个通用的解决方案,也许可以使用union
和可选的一些预处理器宏。
union myptr{
void *ptr;
(whatever-type-that-meets-your-padding-requirment) padding;
};
union myptr myalignedptr;
#define alignedptr (myalignedptr.ptr) /* optional */
推荐阅读
- javascript - 突出显示 Angular 2 中的特定文本
- c# - 防止 FileSystemWatcher 路径重命名
- go - 来自 Opencensus Libraries for Golang 的供应问题
- json - 如何从 JsonNode 获取键值映射?
- android - 如何在android中使用存储库创建会话?
- maven - Maven:如果指定目录中已经存在存储库,是否有任何方法可以拉取和签出到指定的 git 存储库分支?
- javascript - 页面不断重新加载并且更改的图像不会保留
- ios - 金属 IOS 中的网格
- gzip - 使用 zlib 时如何更改 deflate 流输出格式(raw、zlib、gzip)?
- android - 从 Android 项目到 ViewModel 的数据绑定