不完全理解定制的&memcpy'功能在C.

时间:2018-05-23 18:31:51

标签: c utility-method

所以我今天早些时候浏览了Quake引擎源代码,并偶然发现了一些书面实用程序函数。其中一个是Q_memcpy':

Get-ADUser -Credentals (Get-Credentials)

我理解函数的整个前提,但我不太清楚源和目标地址之间按位OR的原因。所以我的问题总结如下:

  • 为什么'计算'得到了相同的逐位算术吗?
  • 为什么结果的最后两位检查是否有差异?
  • 这整个检查的目的是什么?

我确定这是显而易见的事情,但请原谅我的无知,因为在编程方面,我还没有真正钻研过更低层次的事情。我觉得它很有趣,想要了解更多。

3 个答案:

答案 0 :(得分:3)

确定源指针和目标指针是否int对齐,以及count是否是精确的int字节大小。

如果这三件事都是真的,那就是l.s.它们中的2位都是0(假设指针和int是4个字节)。因此算法对这三个值进行OR运算,并将ls分离出来。 2位。

在这种情况下,它会int复制int。否则,它会char复制char

如果测试失败,更复杂的算法会将char的一些前导和尾随字节char以及int的中间字节int复制。

答案 1 :(得分:2)

按位ORing和ANding与3是检查源,目标和count是否可被4整除。如果是,则操作可以使用4字节字,而此代码假定为{{ 1}}为4个字节。否则,操作按字节执行。

答案 2 :(得分:1)

它首先测试所有3个参数是否可以被4整除。如果 - 并且只有 - 它们都是 - 它会一次复制4个字节。

即。这个未解码的将是

if ((long) src % 4 == 0 && (long) dst % 4 == 0 && count % 4 == 0 )
{
    count = count / 4;
    for (i = 0; i < count; i++)
        ((int *)dest)[i] = ((int *)src)[i];
}

我不确定他们是否测试了他们的编译器并且它甚至为测试生成了错误的代码,因此他们决定以这种复杂的方式编写它。在任何情况下,x | y | z都会保证在xy或{{1}中设置的结果中设置 n 位}}。因此,如果z得到0,则没有一个数字设置了2个最低位,因此可以被4整除。

当然使用 now 会相当愚蠢 - 最近的库实现中的标准库(x | y | z) & 3几乎肯定比这更好。

因此,在最近的编译器中,您可以通过将memcpy切换为Q_memcpy优化memcpy的所有来电。 GCC可以使用memcpy生成64位或SIMD移动等内容,具体取决于要复制的区域大小。