c++ - 将标志存储在指针中

标签 c++ pointers

关于在指针中存储外部数据,我听说过很多。 例如在(短字符串优化)中。

例如:

当我们想重载<<时对于我们的 SSO类,取决于我们要打印指针或字符串值的字符串的长度。

而不是创建 bool flag我们可以在指针本身内部编码这个标志。如果我没记错的话,这要感谢 PC 架构,它添加了填充以防止未对齐的内存访问。

但我还没有在示例中看到它。当二进制操作如 & 时,我们如何检测到这样的标志?检查指针是否不允许 RSB 或 LSB 设置为 1(作为标志)?这也不会弄乱取消引用指针吗?

感谢所有回答。

最佳答案

做这样的事情是很有可能的(不像其他人所说的那样)。大多数现代架构(例如 x86-64)强制执行对齐要求,允许您使用指针的最低有效位可能被假定为零的事实,并利用该存储空间其他目的。

让我暂停一下,然后说我将要描述的内容被 C 和 C++ 标准视为“未定义行为”。通过执行我描述的操作,您将以不可移植的方式偏离轨道,但是管理计算机规则的标准比 C++ 标准多(例如处理器程序集引用和体系结构文档)。买者自负。

假设我们在 x86_64 上工作,假设您有一个以指针成员开头的类/结构:

struct foo {
    bar * ptr;
    /* other stuff */
};

根据 x86 架构限制,foo 中的指针必须在 8 字节边界上对齐。在这个简单的示例中,您可以假设每个指向 struct foo 的指针因此都是可被 8 整除的地址,这意味着 foo * 的最低 3 位将为零。

为了利用这样的约束,您必须玩一些转换游戏以允许指针被视为不同的类型。有许多不同的执行转换的方法,从将其转换为 uintptr_t 的旧 C 方法(不推荐)到将指针包装在 union 中的更简洁的方法。为了访问指针或辅助数据,您需要使用位掩码对数据进行逻辑“与”,将您不希望的数据部分归零。

作为这种解释的一个例子,几年前我写了一个 AVL 树,将余额簿记数据下沉到一个指针中,你可以在这里看一下这个例子:https://github.com/jschmerge/structures/blob/master/tree/avl_tree.h#L31 (您需要查看的所有内容都包含在我引用的行的 avl_tree_node 结构中)。

回到您在最初的问题中提到的主题...短字符串优化的实现方式完全不尽相同。它在 Clang 和 GCC 的标准库中的实现有些不同,但都归结为使用 union 来使用指针或字节数组重载存储 block ,并使用字符串的内部长度字段玩一些巧妙的技巧来区分数据是指针还是本地数组。更多细节,这篇博文很好解释:https://shaharmike.com/cpp/std-string/

关于c++ - 将标志存储在指针中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46850555/

相关文章:

通过引用从函数调用的 C++ 构造函数

c++ - 是否有用于使用 gcc 构建 MS Visual C++ Express 的免费开源工具?

c++ - 如何将返回 unique_ptr 的函数转换为原始指针?

c - 动态内存分配和指针相关概念疑惑

python - 如何返回指向ctypes中结构的指针?

c++ - 骨骼动画 : interpolation between transformation matrices (collada)

c++0x std::function 作为方法参数

c - 链接列表中的取消引用错误 - 不是 typedef 错误

Char 指针值在循环中发生变化,但之后不会发生变化

c++ - 是否应该指定返回条件?