【问题标题】:Meaning of applying bitwise or with a pointer address按位或指针地址应用的含义
【发布时间】:2020-10-13 14:26:07
【问题描述】:

虽然我是 ART 实现的 reading this code,但我不明白调用 SET_LEAF 以按位或使用指针地址进行操作的原因

   #define SET_LEAF(x) ((void*)((uintptr_t)x | 1)) 

   *ref = (art_node*)SET_LEAF(make_leaf(key, key_len, value));

我也看到了

#define IS_LEAF(x) (((uintptr_t)x & 1))

查看最低有效位以检查它是否是叶节点。 现在整个参数只有在指针地址是偶数(0x100504080)时才有效。

2 | 1 // 3
3 | 1 // 3

是否保证指针地址在所有架构中始终为偶数?

编辑: 可能重复How come local types always get an even address

上面的问题:无论我有什么样的数据,我可以安全地假设指针总是从事件编号开始吗?

【问题讨论】:

  • 我编辑了问题以减少混淆。最初调用 SET_LEAF 来执行 x | 1 然后调用 IS_LEAF 来检查 x & 1 == 1。这仅在指针地址为偶数时才有效。我的问题是它有保证吗? @MarcoBonelli
  • 这看起来像我未定义的行为......我不确定,但他们将地址转发一个字节的部分对我来说看起来很可疑
  • 这个库看起来并不像所有架构都可以完美移植,它支持一些非 x86 作为事后的想法(具有明显更差的非 SSE2 代码路径)。当然,这仍然是一个有效的问题,但我注意到这一点是为了让您知道会发生什么:速度胜于便携性。
  • 代码通过使用 l.s.b 来避免分配一些大部分浪费的空间。存储标志的指针值。这些指针最终来自对calloc() 的调用,因此代码假设这些指针即使在转换为整数时也是如此。 (旁注:Linux 内核在实现红黑树时使用了类似的技巧。)

标签: c pointers bitwise-operators


【解决方案1】:

这在技术上是未定义的行为,但考虑到他们使用_mm_movemask_epi8 的事实,他们可能并不关心可移植性。在带有标准 glibc malloc 的 x86 中,返回的地址应始终与一个字对齐(64 位中的 8 个字节),这意味着它始终是偶数。

【讨论】:

  • _mm_movemask_ep18 调用在预处理器条件代码中。也有非 x86 代码。代码确实假设malloc(或calloc)将返回一个偶数地址。
猜你喜欢
  • 2020-11-29
  • 2019-07-15
  • 1970-01-01
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 2020-12-30
  • 1970-01-01
相关资源
最近更新 更多