我想使用一个长整数,当设置 MSB 时它将被解释为一个数字,否则它将被解释为一个指针。那么这是否可行,或者我会在 C 或 C++ 中遇到问题吗?
这是在 64 位系统上。
为清楚起见和更好的描述进行了编辑。
在 x86-64 上,您将有一个地址超过 47 位的指针设置了第 63 位,因为“架构支持的最大位数”(当前为 48)以上的所有位都必须具有相同的值作为值本身的最高有效位。(也就是说,任何高于 0007 FFFF FFFF FFFF 的地址都将是 FFF8 0000 0000 0000 - 其间的所有内容都作为指针“无效”)
这很可能只是内核使用的地址,但我不确定它是否保证。
但是,我会尽量避免使用这样的技巧——它很可能会在某个时候卷土重来并困扰你。
那么这是否可行,或者我会在 C 或 C++ 中遇到问题吗?
你有64位吗?您希望您的代码可移植到 32 位系统吗? long
不一定有 64 位。大端与小端?(你知道你的系统是什么吗?)
另外,无可救药的混乱。请只使用一个额外的变量来存储此信息,否则您将遇到许多围绕此的错误。
这取决于架构。例如,x86_64架构当前使用 48 位寻址。这意味着您可以根据自己的需要使用 16 位(有时称为“指针打包”的技巧)。然而,即使 x86_64 架构定义也允许在未来的实现中将此限制提高到完整的 64 位。如果发生这种情况,您可能会遇到需要更改大量代码的情况。因此,如果您真的必须这样做,请确保您的指针包装保存在一个将来易于更改的地方。对于其他架构,您必须自己检查。
除非你真的需要空间,或者你保留了很多这些东西,否则我只会使用一个普通的联合,并添加一个标签字段。如果你打算走那条路,请确保你的记忆符合你的需求。
看看boost::lockfree::detail::tagged_ptr
来自boost.lockfree
这是在最新的 1_53 boost 中引入的类。它将指针和额外的 16 位存储在 64 位变量中。
不要做这样的把戏。如果您需要将整数与某个容器内的指针区分开来,请考虑使用单独bit set
的来指示此类标志。在 C++std::bitset
中可能已经足够好了。
原因:
long unsigned
or long long unsigned
。如果您需要存储它们,请始终应用sizeof()
并void *
键入(如果您需要删除有关指向对象的信息)。如果有问题的“64 位系统”是 x86_64,那么是的,它可以工作。
请记住,返回给您的程序的虚拟地址可能必然与内存中的实际物理地址对齐。事实上,除非您直接操作非常特殊的内存(例如某些形式的图形内存),否则绝对是这种情况。
在这种情况下,它是 MMU 的最大值,它定义了程序看到的指针的值。在这种情况下,对于 x64,我很确定它(当前)是 48 位,但是正如 Mats 在上面指定的那样,一旦你在 48 中设置了最高位,你也会得到 63 位。
因此,接受他的答案和我的答案 - 即使使用少量 RAM,也完全有可能获得第 47 位设置的指针,并且一旦你得到第 63 位设置。