c++ - 可移植标记指针

标签 c++ c pointers

是否有一种可移植的方式在 C/C++ 中实现标记指针,就像一些跨平台和编译器工作的文档化宏一样?或者当你标记你的指针时,你会自担风险?如果存在此类辅助函数/宏,它们是任何标准的一部分还是仅作为开源库提供?

对于那些不知道标记指针是什么但感兴趣的人来说,这是一种在普通指针中存储一些额外数据的方法,因为在大多数体系结构中,指针中的某些位始终为 0 或 1,因此您可以保留自己的在那些额外的位中标记/类型/提示,并在您想要使用指针取消引用某些实际值之前删除它们。

const int gc_flag = 1;
const int flag_mask = 7; // aka 0b00000000000111, because on some theoretical CPU under some arbitrary OS compiled with some random compiler and using some particular malloc last three bits are always zero in pointers.

struct value {
   void *data;
};

struct value val;
val.data = &data | gc_flag;
int data = *(int*)(val.data & flag_mask);

https://en.wikipedia.org/wiki/Pointer_tagging

最佳答案

通过保证对象与 1 << N 的倍数对齐,您可以获得个人使用的地址的最低 N 位。 .这可以通过不同的方式独立于平台实现(alignasaligned_storage 用于基于堆栈的对象或 std::aligned_alloc 用于动态对象),具体取决于您想要实现的目标:

struct Data { ... };

alignas(1 << 4) Data d; // 4-bits, 16-byte alignment
assert(reinterpret_cast<std::uintptr_t>(&d) % 16 == 0);

// dynamic (preferably with a unique_ptr or alike)
void* ptr = std::aligned_alloc(1 << 4, sizeof(Data));
auto obj = new (ptr) Data;
...
obj->~Data();
std::free(ptr);

你付出的代价是丢弃大量内存,随着所需位数呈指数增长。此外,如果您计划连续分配许多此类对象,则此类数组将无法放入处理器的相对较小数组的高速缓存行中,这可能会大大降低程序速度。因此,此解决方案无法扩展

关于c++ - 可移植标记指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47501033/

相关文章:

c++ - 小数点不显示

C++ Poco ODBC 事务 - 自动提交模式

c - IMAP协议(protocol)的解释?

c - 需要一个 C 编程逻辑代码来解决一个简单的难题

c++ - 使用指针c++的问题

c++ - 如何使中心区域调整到 QDockWidgets 位置

c++ - 使 std::array 仅在数组的一部分上调用析构函数

c - C11中const限定符的性能优势

c - 指向结构 : Understanding Element Addressing 的指针

pointers - Golang 复制包含指针的结构