在Linux上,在C / C ++中,指针是否会设置MSB?

时间:2013-05-20 20:50:23

标签: c++ c linux pointers

我想使用一个长整数,当设置MSB时它将被解释为数字,否则它将被解释为指针。那么这项工作还是会在C或C ++中遇到问题?

这是在64位系统上。

为了清晰和更好的描述而编辑。

9 个答案:

答案 0 :(得分:14)

在x86-64上,你将有一个超过47位的指针,地址设置为第63位,因为所有位“高于”架构支持的最大位数“(目前为48位)必须全部都有与值本身的最高位相同的值。 (这是0007以上的任何地址FFFF FFFF FFFF将是FFF8 0000 0000 0000 - 介于两者之间的所有内容都是“无效”作为指针)

这可能只是内核使用的地址,但我不确定它是否可以保证。

但是,我会尽量避免使用这样的技巧 - 它可能会在某些时候回来困扰你。

答案 1 :(得分:6)

人们尝试过这样的技巧before

从长远来看,它永远不会很好。

根本就不要这样做。

编辑:better link - 请参阅“bit31”,之前从未按设置返回。一旦它可以被设置(超过2演出的内存,喘息!)它会打破顽皮的程序,因此一旦这么多的内存成为常态,程序需要选择这个选项,因为人们使用这样的技巧(除其他外)。而现在我的可爱,简短和重点已经变得太长了: - )

答案 2 :(得分:4)

  

那么这会起作用还是会在C或C ++中遇到问题?

你有64位吗?您是否希望您的代码可以移植到32位系统? long不一定有64位。 Big-endian v。little-endian? (你知道你的系统是哪个吗?)

另外,无可救药的混乱。请使用额外的变量来存储此信息,否则您将遇到许多错误。

答案 3 :(得分:3)

这取决于架构。例如,x86_64架构目前正在使用48位寻址。这意味着您可以根据自己的需要使用16位(有时称为“指针打包”)。但是,即使是x86_64体系结构定义也允许在将来的实现中将此限制提升到完整的64位。如果发生这种情况,您可能会遇到可能需要更改许多代码的情况。因此,如果您真的必须这样做,请确保您的指针包装保存在一个容易将来更改的地方。对于其他架构,您必须自己检查。

答案 4 :(得分:1)

boost.lockfree

查看boost::lockfree::detail::tagged_ptr

这是在最新的1_53提升中引入的一个类。它将指针和额外的16个咬合存储在64个咬合变量中。

答案 5 :(得分:1)

除非你真的需要这个空间,否则你会保留很多这些东西,我只会使用一个简单的联合,并添加一个标记字段。如果您要沿着这条路走下去,请确保您的记忆符合您的需求。

答案 6 :(得分:0)

请记住,返回到程序的虚拟地址可能必须与内存中的实际物理地址对齐。事实上,除非你直接操纵相当特殊的记忆[例如,某些形式的图形内存]然后绝对是这种情况。

在这种情况下,它是MMU的最大值,它定义了程序看到的指针的值。在这种情况下,对于x64,我非常确定它(当前)是48位,但正如Mats指定的那样,一旦你在48中设置了最高位,你就会得到63位的说法。

所以拿出他的答案和我的答案 - 完全有可能获得一个第47位的指针,即使有少量的RAM,一旦你这样做,你就得到了第63位。

答案 7 :(得分:0)

不要做这样的伎俩。如果需要将某些容器中的整数与指针区分开来,请考虑使用单独的bit set来指示此类标志。在C ++中,std::bitset可能已经足够了。

原因:

  • 实际上没有人保证指针是long unsignedlong long unsigned。如果你需要 要存储它们,请始终应用sizeof()void *类型(如果需要) 删除有关尖头物体的信息。)
  • 即使在一个系统上,地址也高度依赖于架构。
  • 内核模块可能会严重改变流程的映射逻辑,因此您永远不会知道需要哪些地址。

答案 8 :(得分:0)

如果有问题的“64位系统”是x86_64,那么是的,它会起作用。