简体   繁体   English

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

[英]copy byte-reversed uint64_t to uint8_t array

I know how to reverse the byte order ( convert big endian to little endian in C [without using provided func] ) - in this case I'd like to use __builtin_bswap64 我知道如何反转字节顺序( 在C中将big endian转换为little endian [不使用提供的func] )-在这种情况下,我想使用__builtin_bswap64

I also know how to copy a 64bit uint to a char array - ideally memcopy. 我也知道如何将64位uint复制到char数组-理想地是memcopy。 ( How do I convert a 64bit integer to a char array and back? ) 如何将64位整数转换为char数组并返回?

My problem is the combination of both these. 我的问题是这两者的结合。 At the root of the problem, I'm trying to find a faster alternative to this code: 问题的根源在于,我试图找到一种更快的替代方法:

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);

As memcopy doesn't take the result of __builtin_bswap64 as source argument (or does it?), I tried this: 由于memcopy不会将__builtin_bswap64的结果作为源参数(还是这样做?),因此我尝试了以下操作:

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

but I end up with the error: lvalue required as left operand of assignment 但我最终遇到错误:左值必须作为赋值的左操作数

Is there a faster alternative to the original code I'm trying to replace at all? 是否有比我尝试替换的原始代码更快的替代方法?

This: 这个:

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

parses as 解析为

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

so the left-hand side is a uint64_t , not an lvalue. 因此左侧是uint64_t而不是左值。

So would this work? 这样可以吗?

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

or did you mean to cast upub to uint64_t * first, as Aconcagua commented? 还是您要upub空加瓜所说的那样upubuint64_t *

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

I didn't see the type of upub mentioned, so I can't tell. 我没有看到提到的upub类型,所以我无法分辨。

Also, I have a feeling that there may be an issue with the aliasing rules if upub is originally pointing to another type, so you may want to use something like gcc's -fno-strict-aliasing or make the assignment through a union, or one byte at a time as in your first code snippet. 另外,我感觉如果upub最初指向另一种类型,则别名规则可能会出现问题,因此您可能要使用gcc的-fno-strict-aliasing类的东西,或者通过并集进行赋值,或者如您的第一个代码段中所示,一次写入一个字节。

You can copy as: 您可以复制为:

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

assuming upub is pointer variable 假设upub是指针变量

When writing endian-independent code there is no alternative to bit shifts. 在编写与字节序无关的代码时,除了移位以外别无选择。 You code is likely already close to ideal. 您的代码可能已经接近理想。

What you could play around with is to use a loop instead of hard-coded numbers. 您可以使用的是循环而不是硬编码的数字。 Something along the lines of this: 与此类似:

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

This may turn slower or faster or equal compared to what you already have, depending on the system. 与您现有的设备相比,这可能变得更慢,更快或相等,具体取决于系统。 Overall, it doesn't make any sense to discuss manual optimization like this without a specific system in mind. 总体而言,在不考虑特定系统的情况下讨论这样的手动优化毫无意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM