将标志存储在指针内

storing flag inside pointer

本文关键字:指针 存储 标志      更新时间:2023-10-16

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

例如:

当我们想为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方法(不推荐)到将指针封装在并集中的更干净的方法。为了访问指针或辅助数据,你需要用一个位掩码对数据进行逻辑"answers",将你不希望的部分数据清零。

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

回到你在最初的问题中提到的话题。。。短字符串优化并没有以完全相同的方式实现。Clang和GCC的标准库中的实现有所不同,但两者都可以归结为使用并集来用指针或字节数组重载存储块,并使用字符串的内部长度字段来区分数据是指针还是本地数组。关于更多细节,这篇博客文章非常善于解释:https://shaharmike.com/cpp/std-string/

"在指针内部编码此标志">

不,在C或C++中都不允许这样做。

设置(更不用说取消引用了)指向您不拥有的内存的指针的行为在任何一种语言中都是未定义的。

遗憾的是,您想要实现的是在汇编程序级别完成,指针和整数之间的区别已经足够模糊。