神秘双指针赋值的解释

Kni*_*XIA 2 c pointers

我正在阅读c代码:

 void **alignedData = (void **)(((size_t)temp + aligned - 1)&-aligned); 
Run Code Online (Sandbox Code Playgroud)

我不知道手段,尤其是那&-部分。

谁能解释一下?

谢谢!

Eri*_*hil 6

使用它时,aligned应该是无符号类型(或者 C 实现应该使用二进制补码)并且值是 2 的幂。然后此代码计算要分配的内存量:

  • (size_t) temp转换temp为无符号类型size_t,适用于处理大小。这将是要分配的字节数。
  • (size_t) temp + aligned - 1添加足够的字节以保证aligned在数字temp和之间的某个地方有多个下降temp + aligned - 1,包括。例如,如果temp是37又aligned是8,那么在37和44之间(37+8?1),就有8的倍数(40)。
  • -aligned制作一个位掩码,每个位位置为 1,低位为aligned0的倍数。例如,如果aligned是 8,那么代表的位-aligned是 111…111000,因为最后的 000 位代表 1、2、4 的值,而其他位代表 8、16、32 的值,依此类推.
  • with的&(按位与)然后清除低位,只留下 的倍数位。因此,它产生了区间内的倍数。例如,使用前面提到的 37 和 8 的值,产生 40。(size_t) temp + aligned - 1-alignedalignedaligned((size_t) temp + aligned - 1) & -aligned

因此,此表达式生成temp向上舍入到 的下一个倍数的值aligned。它说“计算我们需要分配的字节数,至少是temp字节数,并且是 的倍数aligned。”

此后,代码将此数字转换为类型void **并使用它来初始化void **alignedData. 那是糟糕的 C 代码。通常没有充分的理由。像这样的大量字节不应用作任何类型的指针。代码可能试图通过其他软件强制使用的数据类型“走私”该值,但可能有更好的方法来做到这一点,例如分配内存来保存该值并提供指向该内存而不是尝试直接转换值。找到更好的解决方案需要了解更多的代码上下文。