将字节反转的uint64_t复制到uint8_t数组

时间:2017-05-05 13:01:24

标签: c arrays int64

我知道如何反转字节顺序(convert big endian to little endian in C [without using provided func]) - 在这种情况下,我想使用__builtin_bswap64

我也知道如何将64位uint复制到char数组 - 理想情况下是memcopy。 (How do I convert a 64bit integer to a char array and back?

我的问题是这两者的结合。问题的根源是,我试图找到一个更快的替代代码:

carr[33] = ((some64bitvalue >> 56) & 0xFF) ;
carr[34] = ((some64bitvalue >> 48) & 0xFF) ;
carr[35] = ((some64bitvalue >> 40) & 0xFF) ;
carr[36] = ((some64bitvalue >> 32) & 0xFF) ;
carr[37] = ((some64bitvalue >> 24) & 0xFF) ;
carr[38] = ((some64bitvalue >> 16) & 0xFF) ;
carr[39] = ((some64bitvalue >> 8) & 0xFF) ;
carr[40] = (some64bitvalue & 0XFF);

由于memcopy没有将__builtin_bswap64的结果作为源参数(或者是吗?),我试过这个:

*(uint64_t *)upub+33 = __builtin_bswap64(some64bitvalue);

但我最终得到了 错误:左值作为赋值的左操作数

是否有更快的替代原始代码我试图替换它?

3 个答案:

答案 0 :(得分:3)

这:

*(uint64_t *)upub+33 = __builtin_bswap64(PplusQ[di][3]);

解析为

(*(uint64_t *) upub) + 33 = __builtin_bswap64(PplusQ[di][3]);

所以左侧是uint64_t,而不是左值。

这会有用吗?

*(uint64_t *) (upub+33) = __builtin_bswap64(PplusQ[di][3]);

或者您的意思是首先将upub投射到uint64_t *,正如Aconcagua所评论的那样?

*((uint64_t *) upub + 33) = __builtin_bswap64(PplusQ[di][3]);

我没有看到提到的upub的类型,所以我无法说出来。

此外,如果upub最初指向其他类型,我觉得aliasing rules可能存在问题,因此您可能希望使用类似gcc' s {{ 1}}或通过联合进行赋值,或者在第一个代码片段中一次进行一个字节。

答案 1 :(得分:1)

您可以复制为:

uint64_t tmp = __builtin_bswap64(some64bitvalue);
memcpy(upub+33,&tmp,sizeof(tmp));

假设upub是指针变量

答案 2 :(得分:1)

当编写与字节无关的代码时,除了位移之外别无选择。您的代码可能已接近理想状态。

你可以使用的是使用循环而不是硬编码的数字。有点像这样:

for(uint_fast8_t i=0; i<8; i++)
{
  carr[i+offset] = (some64bitvalue >> (56-(i*8)) & 0xFF;
}

与现有设备相比,这可能会变慢或变快或变平,具体取决于系统。总的来说,在没有特定系统的情况下讨论这样的手动优化没有任何意义。